打印字符串的C程序表现奇怪

时间:2016-12-21 15:42:07

标签: c

我刚开始使用这个c程序。但它表现得非常奇怪。

此程序假设随机打印a-zA-Z0-9长度取决于用户。

请考虑以下代码。

int main(){

    srand( (unsigned)time( NULL ) );

    int length , i ;
    char alph[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";

    do{

        printf("How many character do you want to print? >>");
        scanf("%d" , &length );

        char* user_length = (char*)malloc( length );

        printf("Strlen - %d\n" , strlen( user_length ) );

        for( i = 0 ; i < length ; i++ ){

            *( user_length + i ) = alph[ rand()%strlen( alph ) ];
        }

        printf("\nString - %s\n" , user_length );
        printf("strlen - %d\n\n" , strlen( user_length ) );

        free( user_length );

    }while( 1 );

    return 0;
}

This is the result I get. (click to view)

唯一的问题是user_length不包含元素的“长度”数

我无法弄清楚错误。有人可以帮我解决这个问题吗?

3 个答案:

答案 0 :(得分:5)

这是一个完全未定义的行为:

    char* user_length = (char*)malloc( length );
    printf("Strlen - %d\n" , strlen( user_length ) );

你只需要分配一个可以被任何字符填充的数组(RAM中某些数据的剩余部分)并询问该数组中字符串的长度,这相当于找到第一个空字符('\ 0')在阵列中。

现在我解释strlen搜索第一个空字符,你必须明白字符串总是以'\0'结束。当您填写user_length字符数组时,您必须在最后添加'\0'或简单0,以使其成为合法字符串。

此外,user_length对于字符串来说是一个可怕的名称,人们会期望一个对应于某个长度的数字。 考虑到所有这些,我会这样做:

int main(){

    srand( time( NULL ) );

    int length , i ;
    char alph[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
    int alph_length = strlen( alph );

    do{
        printf("How many character do you want to print? >>");
        int num_scanned = scanf("%d" , &length );

        if(num_scanned!=1 || length<=0 || length>alph_length) // if the user put some shit, exit
            return -1;


        char* user_string = (char*)malloc( length+1 );

        for( i = 0 ; i < length ; i++ ){
            user_string[i]  = alph[ rand()%alph_length ];
        }
        user_string[length] = '\0';

        printf("string - %s\n"
               "strlen - %zu\n\n" , user_string, strlen( user_string ) );

        free( user_string );

    }while( 1 );

    return 0;
}

请注意,我更正了其他一些内容; - )

答案 1 :(得分:3)

   char* user_length = malloc( length  + 1); // <-- give room for the terminating '\0', and dont cast the return of malloc
    // dont use user_length yet, it contains garbage for the moment

    printf("Strlen - %d\n" , length); 
    for( i = 0 ; i < length ; i++ ){
        *( user_length + i ) = alph[ rand()%strlen( alph ) ]; // ok
    }

    user_length [length] = '\0'; // <-- null-terminate your string

答案 2 :(得分:0)

您忘记将结果置零,这会使strlen和打印都不明确 正确终止,并记住为终结者分配空间(并且不要投射malloc的结果):

char* user_length = malloc(length + 1);
user_length[length] = 0;

(&#34;用户长度&#34;顺便说一下,这个字符串是一个奇怪的名字。)

请注意,您可以在不存储任何内容的情况下生成此内容,但是:

do {
    printf("How many character do you want to print? >>");
    scanf("%d" , &length );

    printf("String: ");
    for( i = 0 ; i < length ; i++ ){
        printf("%c", alph[rand() % strlen(alph)]);
    }
    printf("\n");
} while(1);