C中字符串处理的问题

我被困在HW分配中,我需要编写一个程序,将一堆英语单词(在输入.txt文件中用新行分隔的列表中)转换成一堆Pig拉丁语单词(放入一个列表中)在输出.txt文件中用新行分隔)。 我已经非常接近了,但是我正在使用的strncat函数(字符串连接)函数以某种方式抛出一个新行,这实际上抛弃了我正在打印到stdout的文本(使用它来测试现在)。 任何想法为什么会这样? 这是我的代码:

 #include  #include  #include  #define MAX_STR_SIZE 100 char * convertToPigLatin (char * strPtr, char * pLatinStr); int main(int argc, char *argv[]) { char str[MAX_STR_SIZE]; char pStr[MAX_STR_SIZE]; //char *pStrPtr; FILE *fileInPtr; //Create file name FILE *fileOutPtr; fileInPtr = fopen("pigLatinIn.txt", "r"); //Assign text to file fileOutPtr = fopen("pigLatinOut.txt", "w"); //pStrPtr = pStr; if(fileInPtr == NULL) //Check if file exists { printf("Failed"); exit(-1); } do //Cycles until end of text { fgets(str, 29, fileInPtr); //Assigns word to *char str[29] = '\0'; //Optional: Whole line convertToPigLatin(str, pStr); fprintf(fileOutPtr, "%s", pStr); } while(!feof(fileInPtr)); system("pause"); } char * convertToPigLatin (const char * strPtr, char * pStrPtr) { int VowelDetect = 0; int LoopCounter = 0; int consonantCounter = 0; char pStr[MAX_STR_SIZE] = {'\0'}; char cStr[MAX_STR_SIZE] = {'\0'}; char dStr[] = {'-','\0'}; char ayStr[] = {'a','y','\0'}; char wayStr[] = {'w','a','y','\0'}; pStrPtr = pStr; while (*strPtr != '\0') { if (*strPtr == 'a' || *strPtr == 'e' || *strPtr == 'i' || *strPtr == 'o' || *strPtr == 'u' || VowelDetect ==1) { strncat(pStr, strPtr, 1); VowelDetect = 1; } else { strncat(cStr, strPtr, 1); consonantCounter++; } *strPtr++; } strcat(pStr, dStr); if (consonantCounter == 0) { strcat(pStr, wayStr); } else { strcat(pStr, cStr); strcat(pStr, ayStr); } printf("%s", pStr); // return pStrPtr; } 

这段代码中有各种各样的奇怪之处,但你问的问题是由convertToPigLatin的while循环创建的。 你循环*strPtr != '\0'\n当然不是\0 ,所以你要将pStr添加到pStr

现在对于其余的代码,只需几条评论:

  • 使用strncat复制一个字符是奇怪的用法。 通常,人们会使用简单的字符赋值(如str1[i] = str2[j]
  • *strPtr++正在递增指针并取消引用它,但随后对取消引用的值不执行任何操作。 你只想要strPtr++
  • 您可以使用char str[] = "some string"创建字符串文字。 您不需要使用数组初始化语法。

那些没有详细阅读就跳出来的人。 祝你未来的任务顺利。

编辑以添加使用调试器逐步执行代码在这些情况下非常有价值。 您会看到新行的确切位置。

问题不在于strncat,而是在你的输入中:

 fgets(str, 29, fileInPtr); //Assigns word to *char str[29] = '\0'; //Optional: Whole line 

如果输入的内容不是29个字符,则不会覆盖硬回车。 改为使用它:

 str[strlen(str)-1] = 0; 

..实际上,这将始终覆盖第29个字符,即使它不是一个硬回车(当你输入超过29个字符时)。 所以更好的解决方案是

 char *ptr = strchr(str, '\n'); if (ptr) *ptr = 0; 

您也不能使用MAX_STR_SIZE (您定义的但未在代码中使用),因为fgets

[r]从流中读取字符并将它们作为C字符串存储到str中,直到读取(num-1)个字符或者到达换行符或文件结尾,以先发生者为准。 ( http://www.cplusplus.com/reference/cstdio/fgets/

– 最后一个字符可以是终止零或硬回车。

@selbie是对的,

 *strPtr++; 

==>

 ++strPtr; 

在调用convertToPigLatin之前也要添加它

 if(str[0] == '\0') break; 

并且它有效,pigLatinOut.txt显示拉丁语的工作,但所有在一行!

像这样:(我对拉丁语一无所知,你想要的是什么?):

pigLatinIn.txt

 hello world! I am line one! I am line two! I am line three! 

pigLatinOut.txt

 𬌿\q·ð¬Œ¿\q·ð¬Œ¿\q·ð¬Œ¿\q·