执行scanf和无开关案例

时间:2013-12-12 07:21:45

标签: c

C中的新蜜蜂。这是我的代码(它替换字符串中的字符):

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

void main() 
{
    char str[100], r, ra;
    printf("enter string");
    gets(str);
    int length;
    length= strlen(str);
    printf("length of string is %d",length);
    printf("\nenter the the character that will replace");
    scanf("%c",&r);
    printf("where to replace\n b...begning\ne....ending\np....position");
    scanf("%c",&ra);
    int pos;
    switch(ra)
    {
    case 'b' : str[1]=r; break;
    case 'e' : str[length-1] = r; break;
    case 'p' : printf("enter position");
               scanf("%d",pos);
               if(pos<1 || pos>length-1)
                    printf("please enter a position between 1 and %d",length-1);
               else
                    str[pos]= r;
               break;
    }
    printf("\n after replacing string is  %s", str);  
    getche();

}

问题是IDE没有编译这部分程序,我知道我做错了什么,但是弄不清楚是什么?需要帮助。

    scanf("%c",&ra);
    int pos;
    switch(ra)
    {
    case 'b' : str[1]=r; break;
    case 'e' : str[length-1] = r; break;
    case 'p' : printf("enter position");
               scanf("%d",pos);
               if(pos<1 || pos>length-1)
                    printf("please enter a position between 1 and %d",length-1);
               else
                    str[pos]= r;
               break;
    }

4 个答案:

答案 0 :(得分:3)

使用scanf(" %c",&ra) "%c"。因为使用"%c"阅读会在ra中为您提供垃圾值。而且该值是新行。

当您在a中输入值时,请按p然后Enter key。此Enter key仍保留在stdin流中。

下次当您在ra中阅读时,Enter key中的stdin会在ra中返回。

因此要删除Enter key,您需要阅读" %c"

答案 1 :(得分:2)

scanf(" %c", &ra); //%c之前的空格 与大多数转化不同,%c在转换字符之前不会跳过空格。用户输入数字后,输入缓冲区中会有一个回车符/换行符等待读取 - 这就是%c读取的内容。SO POST

由于同样的原因,您的开关案例无效,因为ra没有预期值

答案 2 :(得分:1)

  

问题是ide没有编译程序的这一部分

嗯,这是一个强烈的指责。而不是假设编译器确实决定不编译部分代码(一时兴起),这是一个更安全的赌注,即你的程序的执行流程不会像你期望的那样进入该部分。

特别是,scanf的行为并不像您认为的那样。它从stdin读取,这是一个缓冲的输入流。 “缓冲”意味着它在读取换行符之前不会为程序提供输入,即直到用户按下返回。但scanf函数族不寻找新行,它将换行符视为普通字符。在您的情况下,扫描"%c"尝试从输入中读取任何字符。随后的"%c"会读取新行,因此您的switch语句中&ra确实是'\n'

我通常觉得使用来自用户的直接输入很困难,但是如果你必须以交互方式提示用户,我建议你首先用fgets读取整行输入,然后分析该行。 sscanf。这消除了看似不同步的输入,并允许您多次扫描一行,可能是替代输入语法。

所以,这是使用这种技术的代码版本:

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

int main() 
{
    char str[100], r, ra;
    char line[20];
    int length;
    int pos;

    printf("enter string");
    fgets(str, 100, stdin);   // note: str includes trailing newline

    length = strlen(str);

    printf("length of string is %d\n", length);
    printf("enter the the character that will replace:\n");
    fgets(line, 20, stdin);
    sscanf(line, " %c ",&r);

    printf("where to replace\n");
    printf("b...begning\ne....ending\np....position\n");
    fgets(line, 20, stdin);
    sscanf(line, " %c ", &ra);

    switch (ra)
    {
    case 'b':   str[1] = r; 
                break;

    case 'e':   str[length - 1] = r; 
                break;

    case 'p':   printf("enter position");
                fgets(line, 20, stdin);
                sscanf(line, "%d ", &pos);

                if(pos < 1 || pos > length-1)
                    printf("please enter a position between 1 and %d",
                        length-1);
                else
                    str[pos]= r; break;
    }

    printf("after replacing string is %s", str);  

    return 0;
}

您的代码仍然存在问题,主要是与C中基于零的数组索引有关。我留给您排序。此外,更喜欢更安全的fgets(buf, len, stdin)而不是gets(str),这不会阻止缓冲区溢出。而您对某个职位的查询应该指向pos的地址,而不只是pos。请养成将新行字符放在printf字符串中的最后一个习惯。它使读取更清晰,并与缓冲输出流的工作方式相匹配。

答案 3 :(得分:0)

程序无法编译,最可能的原因是您使用的是仅支持C89的编译器(我猜它是Visual Studio),或者您使用的是C89模式。

在此代码中:

scanf("%c",&ra);
int pos;
switch(ra)
{

变量pos在块的中间定义,仅在C99之后才支持。解决方案是将所有定义移动到块的开头:

int main() 
{
    char str[100], r, ra;
    int pos;
    printf("enter string");

使用fgets()替换gets(),使用int main替换void main。并使用其他答案所涵盖的scanf解决问题。