所以我对C不是很好,但我正在设计一个读取不区分大小写的文件的GLUT应用程序。为了更容易,我想将我的字符串转换为所有小写字母。我创建了一个函数makeLower,它修改了一个通过引用传入的变量。
我在方法makeLower中有一个While循环,它似乎通过while循环的第一次迭代的一部分,然后EXE崩溃。任何提示都会很棒,谢谢!
输出:
C:\Users\Mark\Documents\Visual Studio 2010\Projects\Project 1\Debug>"Project 1.e
xe" ez.txt
Line is #draw a diamond ring
Character is #
然后错误“项目1.exe已停止工作”
代码:
void makeLower(char *input[]){
int i = 0;
printf("Line is %s\n", *input);
while(input[i] != "\0"){
printf("Character is %c\n", *input[i]);
if(*input[i] >= 'A' && *input[i] <= 'Z'){
*input[i] = tolower(*input[i]);
}
i++;
}
}
int main(int argc, char *argv[]) {
FILE *file = fopen(argv[1], "r");
char linebyline [50], *lineStr = linebyline;
char test;
glutInit(&argc, argv);
while(!feof(file) && file != NULL){
fgets(lineStr , 100, file);
makeLower(&lineStr);
printf("%s",lineStr);
//directFile();
}
fclose(file);
glutMainLoop();
}
答案 0 :(得分:3)
我现在看到更多问题,所以我将评论扩展到答案:
您分配了一个包含50个字符的数组,但告诉fgets
最多可以包含100个字符,这可能会致命,因为fgets
会覆盖不在字符串中的内存。
将C字符串传递给函数时,您不必将指针的地址传递给字符串(&lineStr
),实际的指针或数组是可以的。这意味着您可以将makeLower
功能更改为void makeLower(char *input)
或void makeLower(char input[])
。现在,makeLower
的参数被声明为数组或char指针,而不是指向char数组的指针。
在我上面提到的新makeLower
中,您可以将单个字符作为数组(input[i]
)或指针加偏移量(*(input + i)
来访问。就像我在评论中所说的那样,最后一个版本是编译器可能会创建的,如果你使用第一个版本。但第一个版本更具可读性,所以我建议。
同样在makeLower
中,您与"\0"
进行比较,input[i] != '\0'
是字符串,而不是字符。实际上这几乎是正确的:你应该使用void makeLower(char *input)
{
while (*input != '\0') /* "while (*input)" would also work */
{
*input = tolower(*input);
input++;
}
}
。
最后,我将如何实现它:
strlen
关于功能的一些解释:
strcpy
或*input
)中看到的那样。)*(input + 0)
解除引用(即获取指针指向的值)字符串。它与'\0'
相同,因此获取字符串中第一个字符的值。tolower
(技术上是正常的零),但我们会循环播放。tolower
函数。无论角色是什么,这都会有效,tolower
只会将大写字符变成小写,所有其他字符都会按原样返回。input
复制到第一个字符的结果。这是有效的,因为作业的右侧必须在作业之前执行,因此不会出现任何错误或问题。input
指向字符串中的下一个字符。这是有效的,因为char input[100];
fgets(input, sizeof(input), stdin);
printf("before: \"%s\"\n", input);
makeLower(input);
printf("after : \"%s\"\n", input);
是一个局部变量,因此指针上的操作不会影响调用函数中的任何内容。现在可以像这样调用此函数:
{{1}}
答案 1 :(得分:1)
您是否尝试了(* input [i]!=“\ 0”)而不是您拥有的?由于某种原因,你似乎传递给你的函数一个指向char(* input [])和&amp; lineStr的指针,所以当你检查字符串终结符字符“\ 0”....时,取消引用两次是有意义的。 / p>
只是一个想法,希望它有所帮助
答案 2 :(得分:0)
我认为问题在于你不知道字符串在你想要的时候会等于'\ 0'。所以你可能会超出界限,很可能你不知道字符串的长度。
答案 3 :(得分:0)
据我所知,将'\ 0'传递给tolower()
是很好的。这是一个有效的unsigned char
值,如果输入字符无法进行任何转换,tolower()
只返回输入字符。
因此,循环可以简洁地表示为:
while(input[i] = tolower(input[i]))
++i;
这再次呼叫tolower()
,但它更短,(imo)非常清楚。只是想提一下它。