C 程序在for循环处停止

C 程序在for循环处停止,c,string,char,C,String,Char,我正在用C语言做实验,试图通过创建一个程序来适应记忆和字符串,该程序以单词的形式接受stdin,处理单词,把它们吐出来,并尝试改变单词的大小写 但是,程序似乎除了执行strcpy(key,word)之外,什么都不执行。它就在for循环处停止,甚至不在循环后执行print语句 到目前为止,我已经尝试了while循环和for循环来改变案例。我通过在for循环上方的行上打印来确保密钥复制正确。我甚至注释掉了for循环,看到tolower()调用有两行代码运行并打印出了更新的键。for循环有点问题,我不

我正在用C语言做实验,试图通过创建一个程序来适应记忆和字符串,该程序以单词的形式接受stdin,处理单词,把它们吐出来,并尝试改变单词的大小写

但是,程序似乎除了执行strcpy(key,word)之外,什么都不执行。它就在for循环处停止,甚至不在循环后执行print语句

到目前为止,我已经尝试了while循环和for循环来改变案例。我通过在for循环上方的行上打印来确保密钥复制正确。我甚至注释掉了for循环,看到tolower()调用有两行代码运行并打印出了更新的键。for循环有点问题,我不知道是什么

我怎样才能修好它

int main(void)
{
    char ch; 
    char *word;
    word = (char *)malloc(60 * sizeof(char)); 
    int ind = 0; 
    int cap = 60; 
    while (ch = getchar()) { 
        if (isalnum(ch)) {
            if (ind >= cap) {
                word = (char *)realloc(word, (ind + 1) * sizeof(char));
                cap++; 
            }
            word[ind] = ch; 
            ind++; 
        } else {
            word[ind] = '\0'; 
            int size = strlen(word); 
            char key[size]; 
            strcpy(key, word); 
            for (int i = 0; i < size; i++) {
                if (i = 0) {
                    key[i] = toupper(key[i]);
                } else {
                    key[i] = tolower(key[i]);
                }
            }
            fprintf(stdout, "%s\n", key);
            key[0] = tolower(key[0]);
            fprintf(stdout, "%s\n", key);
            ind = 0; 
            memset(word, 0, sizeof word);
            putchar(ch); 
            putchar('\n');
        }
    }
}
int main(无效)
{
char ch;
字符*字;
word=(char*)malloc(60*sizeof(char));
int ind=0;
int cap=60;
而(ch=getchar()){
if(isalnum(ch)){
如果(ind>=上限){
word=(char*)realloc(word,(ind+1)*sizeof(char));
cap++;
}
单词[ind]=ch;
ind++;
}否则{
字[ind]='\0';
int size=strlen(字);
字符键[大小];
strcpy(关键字、单词);
对于(int i=0;i
您的代码中存在多个问题:

  • ch
    必须使用类型
    int
    定义,以便正确检测
    EOF
    fgetc()
    的返回值可以是字节值(类型为
    unsigned char
    的所有值)或特殊的负值
    EOF
    。转换为类型
    char
    会丢失信息

  • 虽然(ch=getchar())
    无法检测文件结尾,但它仅测试从文件读取的字节是否为非零。您应该在((ch=getchar())!=EOF)时编写

  • 不为空终止符分配空间。更准确地说,在测试目标缓冲区的重新分配时,应该允许额外的2个字节

  • 重新分配数组时,应将
    cap
    增加1以上,以避免重新分配需要存储的每个额外字节

  • int size=strlen(字)可以替换为
    int size=ind

  • char键[size]
    不正确:您应该通过分配一个额外字节来允许空终止符

  • isalnum()
    toupper()
    tolower()
    中的其他函数仅为
    getchar()
    返回的所有值定义。与
    EOF
    不同的负参数值会导致未定义的行为,必须将
    char
    参数转换为
    (未签名的char)
    ,以避免在默认情况下对
    char
    进行签名的体系结构上出现未定义的行为

  • memset(字,0,字的大小)是无用的

  • 您不测试分配失败

  • 你永远不会释放word

以下是修改后的版本:

#include <ctype.h>
#include <stdio.h>

int main(void) {
    int ch; 
    int ind = 0; 
    int cap = 60;
    char *word = malloc(60); 

    if (word == NULL) {
        fprintf(stderr, "allocation failure\n");
        return 1;
    }
    while ((ch = getchar()) != EOF) { 
        if (isalnum(ch)) {
            if (ind >= cap) {
                cap += cap / 2;
                word = realloc(word, cap);
                if (word == NULL) {
                    fprintf(stderr, "allocation failure\n");
                    return 1;
                }
            }
            word[ind] = ch; 
            ind++; 
        } else {
            word[ind] = '\0'; 
            char key[ind]; 
            strcpy(key, word);
            if (ind > 0) {
                key[0] = toupper((unsigned char)key[0]);
                for (int i = 1; i < ind; i++) {
                    key[i] = tolower((unsigned char)key[i]);
                }
            }
            printf("%s\n", key);
            key[0] = tolower((unsigned char)key[0]);
            printf("%s\n", key);
            ind = 0;
            putchar(ch); 
            putchar('\n');
        }
    }
    free(word);
    return 0;
}
#包括
#包括
内部主(空){
int-ch;
int ind=0;
int cap=60;
char*word=malloc(60);
if(word==NULL){
fprintf(stderr,“分配失败\n”);
返回1;
}
而((ch=getchar())!=EOF){
if(isalnum(ch)){
如果(ind>=上限){
上限+=上限/2;
word=realloc(word,cap);
if(word==NULL){
fprintf(stderr,“分配失败\n”);
返回1;
}
}
单词[ind]=ch;
ind++;
}否则{
字[ind]='\0';
字符键[ind];
strcpy(关键字、单词);
如果(ind>0){
键[0]=toupper((无符号字符)键[0]);
for(int i=1;i
字符键[大小]->
字符键[size+1],则字符串NUL终止符还需要一个字符。但是,如果(i=0)
->
如果(i==0)
,可能会出现更多问题。而且
memset(word,0,sizeof word)
是可疑的。为什么不干脆
word[0]=0
*word=0
?我建议您学习如何使用调试器。投入的时间会很快得到回报。哦,天哪,忘了==。我使用memset纯粹是因为我搜索了如何清空一个char数组,这个论坛上的一个线程建议这样做。这个想法是为了让用户能够继续写单词和行。我将尝试您的建议。您是否尝试过在调试器中运行程序并检查它的功能?顺便说一句:
memset(word,0,sizeof word)
或者我建议的替换不是必需的,因为您在下一次循环运行时覆盖了
word
缓冲区。