为什么 break 让我一次脱离 2 个循环以及如何修复它

Why break gets me out of 2 loops at once and how to fix it

好的,所以我的任务想法(我是学生)是允许用户以这种形式插入一串单词:num1_num2_num3..._numN。代码应该创建一个数组 X,动态地给它内存,然后我应该用用户插入的字符串中的数字填充 X。就那么简单。好吧,在函数 stringuniz() 中,我以为我已经弄明白了,但它根本行不通。它很好地获得了第一个数字,但随后停止了,我认为这是因为中断。 Break 的行为(如果我是对的)就像它打破了整个代码而不仅仅是循环。你们知道为什么会这样吗?

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void stringuniz(char *);
int *x;

int main(){

    char s[50];
    int i;

    puts("Unesite string brojeva u formatu br1_br2_...brN: ");
    gets(s);

    stringuniz(s);

    for(i=0;i<(sizeof(x)/sizeof(int));i++)
        printf("%d",x[i]);
}

void stringuniz(char *s){

    int duz,c=0,i,j,k=0,m=0;
    char b[10];

    duz=strlen(s);

    for(i=0;i<duz;i++)
        if(s[i]=='_')
            c++;

    x=(int*)malloc((c+1)*sizeof(int));
    if(x==NULL) exit(1);

    for(i=0;i<c+1;i++){
        for(j=m;j<duz;j++){
            if(s[j]!='_'){
                b[k++]=s[j];
                m++;
            }
            else{
                b[k]='[=10=]';
                x[i]=atoi(b);
                k=0;
                m++;
                break;
            }

        }
    }
}
void stringuniz(char *);
int *x;

int main(){
    [...]
}

void stringuniz(char *s){
    [...]
}

我不知道为什么很多人这样教它,但是在源文件中间的某个地方有 main 绝对没有用,把它放在最后也可以让你摆脱前向声明。所以,我会这样写:

int *x;

void stringuniz(char *s){
    [...]
}

int main(){
    [...]
}

那么你应该开始更多地使用space字符。

    stringuniz(s);

    for(i=0;i<(sizeof(x)/sizeof(int));i++)
        printf("%d",x[i]);

在评论中,alain 已经指出,sizeof(x) 将 return 指针的大小。因此,您需要一种不同的方法来计算数组的大小。一种方法是在 int * x; 之外添加一个变量 size_t x_len;。另外,即使是一行语句也应该使用大括号,相信我,这不仅使代码更具可读性,而且还可以防止在以后的更改中引入错误。

    for (i = 0; i < x_len; i++) {
        printf("%d", x[i]);
    }

.

void stringuniz(char *s){
    int duz,c=0,i,j,k=0,m=0;
    char b[10];

b 将保存用户输入的单词。如果他的单词超过 9 个字符,就会出现缓冲区溢出。

    duz=strlen(s);

    for(i=0;i<duz;i++)
        if(s[i]=='_')
            c++;

您正在计算此处的字数。因此,请使用更具描述性的名称,例如 num_words 而不是 c。顺便说一句:这就是上面提到的x_len

    x=(int*)malloc((c+1)*sizeof(int));

无需转换 malloc 的 return 值。实际上它可能隐藏错误。此外,我会使用 sizeof(*x) 而不是 sizeof(int),因为如果您在语句中更改 x 的类型,您还必须更改 malloc 调用。在我的声明中,不需要以任何方式触及 malloc 调用。

    x = malloc((c+1) * sizeof(*x));

    if(x==NULL) exit(1);

    for(i=0;i<c+1;i++){
        for(j=m;j<duz;j++){
            if(s[j]!='_'){
                b[k++]=s[j];

您不断地用正在阅读的下一个单词覆盖 b。反正你不使用它,你可以跳过这一行。

                m++;
            }
            else{
                b[k]='[=18=]';
                x[i]=atoi(b);
                k=0;
                m++;
                break;

而这个 break; 只突破了最里面的 for (j 循环。

            }
        }
    }
}

这个

(sizeof(x)/sizeof(int) 

不会给你数组的大小。 sizeof(x)int* 的字节大小(可能是 4 或 8)。 您需要记住字符串中 _ 的数量所暗示的大小。

此外,您还存在一些差一错误,为了将来参考,您可能希望为您决定 post 公开的代码选择更具描述性的变量名称。

一旦我将代码更改为:

,代码对我有用
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void stringuniz(char *);
int *x;
int x_size = 0;

int main(){
    char s[50];
    int i;
    puts("Unesite string brojeva u formatu br1_br2_...brN: ");
    fgets(s,50,stdin);
    stringuniz(s);
    for(i=0;i<x_size;i++)
        printf("%d\n",x[i]);
}
void stringuniz(char *s){
    int duz,c=0,i,j,k=0,m=0;
    char b[10];
    duz=strlen(s);
    for(i=0;i<duz;i++)
        if(s[i]=='_')
            c++;
    x=malloc((c+1)*sizeof(int));
    x_size = c+1;
    if(x==NULL) exit(1);
    for(i=0;i<=c+1;i++){
        for(j=m;j<=duz;j++){
            if(s[j]!='_' && s[j]!='[=11=]'){
                b[k++]=s[j];
                m++;
            }
            else {
                b[k]='[=11=]';
                x[i]=atoi(b);
                k=0;
                m++;
                break;
            }

        }
    }
}