繁体   English   中英

覆盖未知长度的字符串以解决小写问题

[英]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++;
    }
}

有关该功能的一些解释:

  • 可以将所有char数组转换为char指针,但不能相反。 传递char指针实际上是传递字符串的最常用方法,正如您从所有接受字符串的标准函数(如strlenstrcpy )中所看到的那样。
  • 表达式*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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM