[英]Coverting an unknown length string to lower case issues
因此,我对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();
}
我现在看到了更多问题,因此我将评论扩展到一个答案:
您分配了一个由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"
进行比较, "\\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);
您是否尝试了while(* input [i]!=“ \\ 0”)而不是您拥有的东西? 由于某种原因,您似乎将指向char(* input [])和&lineStr的指针传递给函数,因此在检查字符串终止符“ \\ 0”时,应两次取消引用。...
只是一个想法,希望对您有所帮助
我认为问题是您不希望该字符串等于'\\ 0'。 因此,您可能会超出范围,这很可能是您不知道字符串的长度。
据我了解,可以将'\\ 0'传递给tolower()
。 这是有效的unsigned char
值,并且tolower()
仅在无法进行任何转换tolower()
返回输入字符。
因此,可以将循环简写为:
while(input[i] = tolower(input[i]))
++i;
这会再调用一次tolower()
,但它更短,并且(imo)很清楚。 只是想提一下它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.