K& R C和字符串 [英] K&R C and strings

查看:96
本文介绍了K& R C和字符串的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想知道是否有人有时间根据这些数据编写一个小例子程序或批评我自己的努力?


一个名为Realm的文件List.html包含以下数据:

Bladefist-Horde

Nordrassil-Horde

德拉诺联盟

Nordrassil -Alliance

Nordrassil-Neutral

德拉诺部落

月光君王部落

影月部落

月光林地 - 联盟


我需要一个算法,从这个列表中获取领域的名称

我们有联盟和部落的数据和将它们列在

按字母顺序排列。我希望这个列表的格式是:

德拉诺联盟

德拉诺部落

月光林地 - 联盟

月光林地部落

诺达希尔联盟

诺达希尔部落


我致力于使用ANSI C和K& R书作为我的向导。它说一个

字符串是一个字符数组。


现在我可以打开文件,我可以使用strtok分割每行但是

我不知道如何创建这些字符串的数组?


FILE * realmList;

if((realmList = fopen(Realm List.html,w +))== NULL)

{

printf(无法打开\ " Realm List.html \" for output \ n");

返回1;

}


/ *

列出领域和每个的数量

* /

char strLine [244];


while(fgets(strLine,244,realmList))

{


char * tmp = NULL;

char token [] =" - " ;;

tmp = strtok(strLine,token);


printf("%s \ n",tmp );

/ *此时卡住* /

}

解决方案

< blockquote> pkirk25 schrieb:


我想知道是否有人有时间根据这些数据编写一个小例子程序或批评我自己的努力?


一个名为Realm List.html的文件包含以下数据:

Bladefist-Horde

Nordrassil-Horde

德拉诺联盟

诺达希尔联盟

诺达希尔 - 中立

德拉诺部落

月光林地部落

影月部落

月光林地 - 联盟


我需要一个算法,从这个列表中取出我们同时拥有联盟和联盟的领域的名称

部落的数据以及按字母顺序排列在
字母顺序中。我希望这个列表的格式是:

德拉诺联盟

德拉诺部落

月光林地 - 联盟

月光林地部落

诺达希尔联盟

诺达希尔部落


我承诺使用ANSI C



好​​的。请注意,这可能不是最佳的。或最简单语言

用于此任务。


以K& R书作为我的向导。它说一个

字符串是一个字符数组。



啊,仔细阅读。 char数组只包含一个字符串,如果

它包含至少一个''\ 0''字符,即

char a [] = {''h' ','''','''','''',''o''};

不是字符串,而

char a [] = {''h'',''e'','l'','l'',''\ 0''};

或等效地

char a [] =" hell";

is。

char a [] = {''h'',''\\ \\ 0'','''','''',''\ 0''};

还包含一个字符串(h);
< blockquote class =post_quotes>
现在我可以打开文件了,我可以用strtok分割每行但是

我不知道如何创建这些数组字符串?


FILE * realmList;

if((realmList = fopen(" Realm List.html"," w +"))= = NULL)



注意:这实际上删除了Real的内容m List.html"。

你可能想要r +或者仅仅是r如你所说,你想要从文件中输入你的输入数据。


{

printf( 无法打开\Realm List.html \" for output \ n");

返回1;

}


/ *

列出领域和每个的数量

* /


char strLine [ 244];


while(fgets(strLine,244,realmList))



注意这种方法有问题:

- fgets()不一定会给你整行,但在这种情况下只有

,最多为244-2非''\ n''字符。 />
- 你还需要一些新的存储将

a的读取字符串放在一起。

看看CB Falconer的fggets(),它给你全线

并为他们分配存储空间。
http://cbfalconer.home。 att.net/download/


{


char * tmp = NULL;

char token [] =" - " ;;

tmp = strtok(strLine,token);



这有效地破坏了你的输入,即你无法按照-Alliance排序

。或-Horde后缀。

你可以用strchr()交替找到第一个'' - '并存储

的位置。


printf("%s \ n",tmp);



如果你只有strchr()的位置,你可以使用

精度字段只打印一定数量的字符

a string。

printf("。* s \ n",numChars,strLine);


你想要一个可变大小字符串的数组,因此,有一个指向字符串的第一个字符的指针数组是一个更好的

解决方案。

此外,你事先不知道数组的大小,所以

使用分配的存储可能是最好的解决方案。

循环之前:

size_t size = YOUR_START_SIZE;

size_t count = 0;

char **字符串;

char * strLine;

int ErrOrEOF;

....


Strings = malloc((size + 1)* sizeof * Strings);

if(NULL == Strings){

/ *你的错误处理在这里* /

}


循环:


while(!(ErrOrEOF = fggets(& strLine,realmLi) st))){

if(count> = size){

char ** tmp = realloc(Strings,(2 * size + 1)* sizeof * Strings );

if(NULL == tmp){

/ *你的错误处理在这里* /

}

Strings = tmp;

size * = 2;

}

字符串[count ++] = strLine;

}

if(EOF!= ErrOrEOF){

/ *发生错误* /

}


以上未经过测试。

一旦你完成编译和工作,你就有了计数。字符串。

您可以使用qsort()对它们进行排序。


干杯

Michael

- -

电子邮件:我的是/ at / gmx / dot / de地址。


2006年9月24日11:43:21 -0700,pkirk25 < pa ***** @ kirks.netwrote:


>我想知道是否有人有时间编写基于
的小示例程序数据或批评我自己的努力?



#include< stdio.h>

#include< stdlib.h>

#include < string.h>


#ifndef strdup

char * strdup(const char * s){

char * r ;

返回(r = calloc(strlen(s)+1,1))?strcpy(r,s):0;

}

#endif


char * read_str(char * s,int max){

char * r = fgets(s,max,stdin);

if(r){

int len = strlen(s);

if(len&& s [len-1] = =''\ n'')

s [len-1] =''\ 0'';

}

返回r ;

}


typedef struct node_tag {

char * name;

struct node_tag * next ;

} node_t,* pnode_t;


pnode_t node_new(const char * n){

pnode_t i = malloc(sizeof * i);

if(i){

i-> next = 0;

i-> name = strdup(n );

}

返回i;

}


void node_free(pnode_t self ){

if(self){

if(self-> name)free(self-> name);

free(自我);

}

}


void list_print(pnode_t head){

if( head){

puts(head-> name);

list_print(head-> next);

}

else printf("(列表末尾)\ n");

}


void list_free(pnode_t head){

if(head){

list_free(head-> next);

node_free(head);

}

}


void list_insert(pnode_t * phead,pnode_t new_node){

if(!* phead)

* phead = new_node;

else

if(strcmp(new_node-> name,(* phead) - > name)< = 0 ){

new_node-> next = * phead;

* phead = new_node;

}

else

list_insert(&(* phead) - > next,new_node);

}


int main(){

pnode_t head = 0;


list_insert(& head,node_ne w(Bladefist-Horde));

list_insert(& head,node_new(" Nordrassil-Horde"));

list_insert(& head, node_new(" Draenor-Alliance"));

list_insert(& head,node_new(" Nordrassil-Alliance"));

list_insert(& head, node_new(" Nordrassil-Neutral"));

list_insert(& head,node_new(" Draenor-Horde"));

list_insert(& head, node_new(月光林地 - 部落));

list_insert(& head,node_new(" Shadowmoon-Horde));

list_insert(& head, node_new(月光林地 - 联盟));


list_print(头);

list_free(头);


返回0;

}


两个很棒的答案。


谢谢 - 如果我可以让它全部融合在一起我很可能成为第一个

魔兽世界黄金百万富翁!


I wonder if anyone has time to write a small example program based on
this data or to critique my own effort?

A file called Realm List.html contains the following data:
Bladefist-Horde
Nordrassil-Horde
Draenor-Alliance
Nordrassil-Alliance
Nordrassil-Neutral
Draenor-Horde
Moonglade-Horde
Shadowmoon-Horde
Moonglade-Alliance

I need an algorithm that takes from this list the names of Realms that
we have both Alliance and Horde data for and to list them in
alphabetical order. My desired format of this list will be:
Draenor-Alliance
Draenor-Horde
Moonglade-Alliance
Moonglade-Horde
Nordrassil-Alliance
Nordrassil-Horde

I''m committed to using ANSI C with the K&R book as my guide. It says a
string is an array of chars.

Right now I can open the file, I can use strtok to split each line but
I can''t work out how to create an array of these strings?

FILE *realmList;
if((realmList=fopen("Realm List.html","w+")) == NULL)
{
printf("Couldn''t open \"Realm List.html\" for output\n");
return 1;
}

/*
List Realms and count of each
*/
char strLine[244];

while (fgets(strLine, 244, realmList))
{

char *tmp = NULL;
char token[] = "-";
tmp = strtok(strLine, token);

printf("%s\n", tmp);
/* stuck at this point */
}

解决方案

pkirk25 schrieb:

I wonder if anyone has time to write a small example program based on
this data or to critique my own effort?

A file called Realm List.html contains the following data:
Bladefist-Horde
Nordrassil-Horde
Draenor-Alliance
Nordrassil-Alliance
Nordrassil-Neutral
Draenor-Horde
Moonglade-Horde
Shadowmoon-Horde
Moonglade-Alliance

I need an algorithm that takes from this list the names of Realms that
we have both Alliance and Horde data for and to list them in
alphabetical order. My desired format of this list will be:
Draenor-Alliance
Draenor-Horde
Moonglade-Alliance
Moonglade-Horde
Nordrassil-Alliance
Nordrassil-Horde

I''m committed to using ANSI C

Okay. Note that this may not be the "best" or "easiest" language
for this task.

with the K&R book as my guide. It says a
string is an array of chars.

Ah, read more closely. An array of char only contains a string if
it contains at least one ''\0'' character, i.e.
char a[] = {''h'', ''e'', ''l'', ''l'', ''o''};
is not a string while
char a[] = {''h'', ''e'', ''l'', ''l'', ''\0''};
or, equivalently,
char a[] = "hell";
is.
char a[] = {''h'', ''\0'', ''l'', ''l'', ''\0''};
also contains a string ("h");

Right now I can open the file, I can use strtok to split each line but
I can''t work out how to create an array of these strings?

FILE *realmList;
if((realmList=fopen("Realm List.html","w+")) == NULL)

Note: This effectively deletes the contents of "Realm List.html".
You probably want "r+" or just "r" as you stated that you want to
_read_ your input data from the file.

{
printf("Couldn''t open \"Realm List.html\" for output\n");
return 1;
}

/*
List Realms and count of each
*/
char strLine[244];

while (fgets(strLine, 244, realmList))

Note that this approach has problems:
- fgets() does not necessarily give you the whole line but only
in this case up to 244-2 non-''\n'' characters.
- You still need some "new" storage to put the read string for
a while.
Have a look at C.B. Falconer''s fggets() which gives you full lines
and allocates the storage for them.
http://cbfalconer.home.att.net/download/

{

char *tmp = NULL;
char token[] = "-";
tmp = strtok(strLine, token);

This effectively destroys your input, i.e. you cannot sort according
to the "-Alliance" or "-Horde" suffix.
You could alternately find the first ''-'' with strchr() and store that
position.

printf("%s\n", tmp);

If you just have the position from strchr(), you can use the
precision field to print only a certain number of characters from
a string.
printf(".*s\n", numChars, strLine);

You want an array of variably sized strings, so, having an
array of pointers to the first characters of strings is a better
solution.
Moreover, you do not know the size of the array beforehand, so
using allocated storage may be the best solution.
Before the loop:
size_t size = YOUR_START_SIZE;
size_t count = 0;
char **Strings;
char *strLine;
int ErrOrEOF;
....

Strings = malloc((size+1) * sizeof *Strings);
if (NULL == Strings) {
/* your error handling here */
}

The loop:

while (!(ErrOrEOF = fggets(&strLine, realmList))) {
if (count >= size) {
char **tmp = realloc(Strings, (2*size+1) * sizeof *Strings);
if (NULL == tmp) {
/* your error handling here */
}
Strings = tmp;
size *= 2;
}
Strings[count++] = strLine;
}
if (EOF != ErrOrEOF) {
/* An error occurred */
}

The above is not tested.
As soon as you got it to compile and work, you have "count" strings.
You can sort them using qsort().

Cheers
Michael
--
E-Mail: Mine is an /at/ gmx /dot/ de address.


On 24 Sep 2006 11:43:21 -0700, "pkirk25" <pa*****@kirks.netwrote:

>I wonder if anyone has time to write a small example program based on
this data or to critique my own effort?

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#ifndef strdup
char *strdup(const char *s) {
char *r;
return (r=calloc(strlen(s)+1,1))?strcpy(r,s):0;
}
#endif

char *read_str(char *s, int max) {
char *r=fgets(s, max, stdin);
if (r) {
int len=strlen(s);
if (len && s[len-1]==''\n'')
s[len-1]=''\0'';
}
return r;
}

typedef struct node_tag {
char *name;
struct node_tag *next;
} node_t, *pnode_t;

pnode_t node_new(const char *n) {
pnode_t i=malloc(sizeof *i);
if (i) {
i->next=0;
i->name=strdup(n);
}
return i;
}

void node_free(pnode_t self) {
if (self) {
if (self->name) free(self->name);
free(self);
}
}

void list_print(pnode_t head) {
if (head) {
puts(head->name);
list_print(head->next);
}
else printf("(end of the list)\n");
}

void list_free(pnode_t head) {
if (head) {
list_free(head->next);
node_free(head);
}
}

void list_insert(pnode_t *phead, pnode_t new_node) {
if (!*phead)
*phead=new_node;
else
if (strcmp(new_node->name, (*phead)->name)<=0) {
new_node->next=*phead;
*phead=new_node;
}
else
list_insert(&(*phead)->next, new_node);
}

int main() {
pnode_t head=0;

list_insert(&head, node_new("Bladefist-Horde"));
list_insert(&head, node_new("Nordrassil-Horde"));
list_insert(&head, node_new("Draenor-Alliance"));
list_insert(&head, node_new("Nordrassil-Alliance"));
list_insert(&head, node_new("Nordrassil-Neutral"));
list_insert(&head, node_new("Draenor-Horde"));
list_insert(&head, node_new("Moonglade-Horde"));
list_insert(&head, node_new("Shadowmoon-Horde"));
list_insert(&head, node_new("Moonglade-Alliance"));

list_print(head);
list_free(head);

return 0;
}


Two great answers.

Thanks - if I can make it all fit together I may well become the first
World of Warcraft gold millionaire!


这篇关于K&amp; R C和字符串的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆