如果输入非常大,程序会异常终止

时间:2011-10-13 14:13:12

标签: c

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

#define n ((sizeof(char)) * 100 )

int stringlength(char * str)
{
    int count=0;
    while(*str)
    {  
        if(*str == '\n')
        {
            *str=0;
        }
        else
            count++, str++;
    }
    return count;
}


int palin1(char *str, int k)
{
    char * pend = str + k - 1;
    if(*pend != *str)
        return 0;
    else
        palin1(str+1, k-1);
       return 1;
}    

int palin(char *str)
{
    int length = stringlength(str), f=0;
    char *pend = str + length - 1;
    while(str <= pend)
    {
        if(*str == *pend) f=1;
        else
            return (f = 0);
        str++, pend--;
    }
    return 1;
}

main()
{
    char * ps = (char *)malloc(n);
    int flag;
    if(ps == NULL) printf("Malloc Fail\n");
    else
    {
        printf("Malloc Succeeded, you have memory of %d bytes\n", n);
        printf("This program checks if String is Palindrome or not\n\
        \nEnter your String: ");
        fgets(ps, 100, stdin);
        printf("You entered: %s of length %d", ps, stringlength(ps));
        int i = 0;
        printf("\n\nEnter:\n1.Using iteration\n2.Using Recursion ");
        scanf("%d", &i);
        switch(i)
        {
            case 1:
                flag=palin(ps);
                break;
            case 2:
                flag=palin1(ps,stringlength(ps));
                break;
            default:
                printf("Invalid input");
        }

        if(flag) printf("\nYou entered a Palindrome");
        else  printf("\nNot a Palindrome");
    }
    free (ps);
    return 0;
}

为什么上面的程序http://www.ideone.com/qpGxi没有给出输入的任何输出:

  

mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm

我知道fgets(ps,100,stdin)只会占用100个字符而不会超过100个字符,但为什么程序会暂停执行?

3 个答案:

答案 0 :(得分:1)

您应按照fgets spec的建议检查fgets失败。

if ( fgets(ps,100,stdin) == NULL ) {
    printf("Input failed.");
    //check for 'feof' or 'ferror' here
    return -1;
}
printf("You entered: %s of length %d",ps,stringlength(ps));

我不明白为什么fgets会失败,但你会得到一个未初始化的字符缓冲区,这会导致printf崩溃。

编辑:您也应该注意编译器警告。

prog.c:49: warning: return type defaults to ‘int’
prog.c: In function ‘main’:
prog.c:59: warning: ignoring return value of ‘fgets’, declared with attribute warn_unused_result
prog.c:63: warning: ignoring return value of ‘scanf’, declared with attribute warn_unused_result
prog.c: In function ‘palin’:
prog.c:46: warning: control reaches end of non-void function
prog.c: In function ‘main’:
prog.c:52: warning: ‘flag’ may be used uninitialized in this function

您甚至可以看到编译器建议将fgets检查为null。另外,在默认情况下,flag应设置为0,否则如果用户输入12以外的其他内容,您将获得未定义的行为。

编辑2:哦,基督的缘故!你的程序运行正常!您忘了在Ideone !!!

中查看“运行程序”

http://www.ideone.com/7ecZd

答案 1 :(得分:0)

它正在终止,因为如果输入太大,输入流中会留下字符。例如,如果您希望使用fgets仅使用 5 字符,但输入为 -

  

的StackOverflow

Overflow留在输入流中。需要从流中删除它们以进行进一步的输入操作才能成功。因此,使用 -

从流中删除这些额外的字符
fgets(ps,100,stdin);
while (getchar() != '\n');

由于输入流受到违规字符的攻击,实际接受用户输入的scanf语句无效并跳转到后续操作。

同时将flag变量初始化为 0 ,否则它会有垃圾值。

答案 2 :(得分:0)

你不能像那样打破字符串文字

printf("%s\n", "string literal **WRONGLY**\n
broken right after the line break.");

你可以做的是使用加入连续字符串文字的预处理器功能来制作一个

printf("%s\n", "string literal **CORRECTLY**\n"
"broken because the preprocessor joins these 2 parts.");