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·