String 输入带空格的字符串后,Scanf一直等待输入?

String 输入带空格的字符串后,Scanf一直等待输入?,string,input,scanf,spaces,String,Input,Scanf,Spaces,这是捕获字符串的函数: void capture(char string[]) { printf("_____________________________________________________________\n\n"); printf("Ingrese una cadena: "); scanf(" %[^\n]s", string); printf("Cadena capturada: %s\n", string); printf("__

这是捕获字符串的函数:

void capture(char string[]) {
    printf("_____________________________________________________________\n\n");
    printf("Ingrese una cadena: ");
    scanf(" %[^\n]s", string);
    printf("Cadena capturada: %s\n", string);
    printf("_____________________________________________________________\n\n");
}
这是在主函数中调用的函数:

    void sort(char string[]) {  
int opt, i, j, temp = 0;
char string_copy[50];
strcpy(string_copy, string);
for (i = 0; string_copy[i] != '\0'; i++) 
    for (i = 0; string_copy[i] != '\0'; i++) {
        for (j = i + 1; string_copy[j] != '\0'; j++) {
            if (string_copy[i] > string_copy[j]) {
                temp = string_copy[i];
                string_copy[i] = string_copy[j];
                string_copy[j] = temp;
            }
            }
            }

printf("_____________________________________________________________\n\n");
printf("Ordenar de modo:\n1) Ascendente\n2) Descendente\n");
printf("Seleccione una opcion: ");
fflush(stdin);
scanf(" %d", &opt);
switch(opt) {
    case 1: 
            printf("'%s' ordenado de forma ascendente: %s\n", string, string_copy);
            break;
    case 2: 
            printf("'%s' ordenado de forma descendente: ", string);
            for (i=strlen(string); i != 0; i--)
                printf("%c", string_copy[i]);
            printf("\n");
            break;
    default: printf("[ ! ] Selección incorrecta!\n"); break;
}
printf("_____________________________________________________________\n\n");
}

//Imprimir la última palabra de la cadena
void last_word(char string[50]) {
    printf("_____________________________________________________________\n\n");
    int i, count = 0;
    for (i=0; string[i] != '\0'; i++) {
        if (string[i] == ' ') {
            count = i;
        }
    }
    if (count == 0) {
        printf("Solamente hay una palabra: %s\n", string);
    } else {
        printf("La última palabra en '%s' es: ", string);
        for (i=count; string[i] != '\0'; i++) {
            printf("%c", string[i]);
        }
        printf("\n");
    }
    printf("_____________________________________________________________\n\n");
}
这是有问题的代码:

int main() {
int opc = 0;
char string[50];
do {
    printf("MENU:\n");
    printf("1) Capturar cadena\n");
    printf("2) Sustituir un caracter por otro\n");
    printf("3) Buscar un caracter e imprimir el número de veces que aparece\n");
    printf("4) Buscar un caracter para eliminar de la cadena.\n");
    printf("5) Ordenar los caracteres alfabéticamente\n");
    printf("6) Imprimir la última palabra de la cadena\n");
    printf("0) Salir\n");
    printf("Seleccione una opcion: ");
    scanf("%i", &opc);
    printf("Opcion: %d", opc);
    switch(opc) {
        case 1:{
                capture(string);
                break;
        }
        case 2:{
                replace(string);
                break;
        }
        case 3:{
                num_char(string);
                break;
        }
        case 4:{
                delete(string);
                break;
        }
        case 5:{
                sort(string);
                break;
        }
        case 6:{
                last_word(string);
                break;
        }
        case 0:{
                printf("Bye\n");
                break;
        }
        default: {
                printf("[ ! ] Selección incorrecta!\n");
        }
    }
} while (opc != 0);

    return 0;
}
问题在于上面的选项5在开关情况下:它只在捕获的字符串没有任何空格时执行。例如,如果您输入“Hello world”。案例5永远不会执行,scanf

printf("Seleccione una opcion: ");
scanf("%i", &opc);
只会呆在那里等待输入。我重复一遍,只有当捕获的字符串有空格并且在switch case中选择选项5时,才会发生这种情况

            capture(&string[50]);
您正在传递
capture
字符串[50]的地址。但是没有
字符串[50]
。因此,您正在将一个超过
字符串结尾的地址传递给
capture
。(因为
string
有50个条目,
0
是第一个条目,
49
是最后一个条目。没有
string[50]
,它已经超过了数组的末尾

void capture(char string[50]) {
    printf("_____________________________________________________________\n\n");
    printf("Ingrese una cadena: ");
    scanf(" %[^\n]s", string);
    printf("Cadena capturada: %s\n", string);
    printf("_____________________________________________________________\n\n");
}

oops,
capture
写入到
string
过去的地址,但这已经超过了您分配的数组的结尾。写入到您分配的边界之外的内存可能会破坏其他变量并导致不可预测的结果。在您修复越界写入之前,您实际上无法调试程序中的任何其他内容。您可以使用
valgrind
或类似工具来帮助检测此类错误。

我试图理解您的逻辑,但似乎存在问题:

为什么要将字符串[50]传递给每个函数?我假设您希望在每个函数中使用相同的字符串变量,因此,有两点需要检查:

  • 例如,您应该要求用户在switch()行之前的行中的switch()语句-call capture()之前输入字符串值。否则,用户可以在输入“capture”之前输入其他菜单选项函数,在这种情况下,字符串将不存在,从而导致分段错误-如果我没有弄错的话。(您尝试过吗?例如,在选择选项1之前,选择选项3?它一定不起作用)

  • 要通过参数传递“string”变量,请使用“string”,而不是“string[50]”。 在声明之后(其中“50”是字符串的大小),表达式“string[50]”表示字符串的第50个值,正如David的回答所指出的,该值甚至不存在


  • 我想知道函数
    sort
    ..@GenoChen是否有错误或无休止的循环将sort函数添加到原始帖子中。@DavidSchwartz,因为如果没有,Visual Basic会给我错误“分段错误(核心转储)”:(@UrielGuzmán如果你为了修复bug而做出了不理解的更改,那么你应该在寻求帮助之前将其删除,并发布你认为应该有效的代码。否则,你得到的帮助可能会让你回到最初的状态,更糟糕的是,这是关于你不理解也不会编写的代码的建议。(很可能我给你的答案只是让你回到了破译代码之前的状态,更努力地修复代码。对不起。)@DavidSchwartz谢谢。我在原始帖子中修复了数组问题。但是问题仍然存在。似乎我没有正确地将数组传递给函数。在原始帖子中修复了这个问题。但是,问题仍然存在。PS:程序在等待输入时崩溃。它看起来也像一个无限循环问题。你击中了函数的核心问题。我在我的设备上尝试了gdb,发现
    return 0;
    of
    main
    后堆栈崩溃。但我不知道为什么会出现在这个语句中。哦,对于原始问题的代码,甚至
    string
    string\u copy
    都被重写成了一些意外的值……是的。David是正确的。已经更正了几分钟前,ted在原始帖子中输入了字符串参数。(它现在传递的是字符串,而不是&string[50]).但是,在我更正之后,分割错误消失了。但是问题的原始问题仍然存在。我也只是按照你在第1点中所说的做了。尽管它没有解决问题。我会像你说的那样保留它,因为,正如你说的,最好先捕获字符串。你检查了第1期吗?我也不理解函数capture()中的行“scanf(“%scanf[^\n]s”,string);”。您尝试过只使用“scanf(“%50c”,string)”吗?%s读取任意数量的非空白字符,在找到的第一个空白字符处停止。终止的空字符将自动添加到存储序列的末尾。发件人:您在那里查看……对不起,我输入了一个错误。我的意思是我更正了问题1(和问题2)。scanf(“%[^\n]s”,字符串);用于接受带空格的字符串,在遇到换行符之前停止。我首先留下了一个空格,因为选项菜单的换行符与scanf混淆。尝试了fgets(),甚至使用了getchar()要吃掉换行符,但它们似乎与原始问题无关。我明白了。我现在需要离开,但如果问题仍然存在,我可以稍后尝试帮助您。我在上一条评论中为您推荐了一个链接,希望它能帮到您……”