一个具体的变量引用被跳过

问题描述 投票:0回答:3

这似乎是在最后%sprintf完全被跳过。

这是整个代码:

#include <stdio.h>

int main(void){
    char address[100];
    char city[100];
    char state[2];
    char zip[15];

    printf("Enter street address: ");
    scanf(" %[^\n]",&address);

    printf("Enter city: ");
    scanf(" %[^\n]",&city);

    printf("Enter state: ");
    scanf(" %s",&state);

    printf("Enter ZIP Code: ");
    scanf(" %s",&zip);

    printf("%s\n%s, %s %s",address,city,state,zip);

    return 0;
}

当输入该地址:

1 Main Street
New York City, NY 12345

该程序打印:

1 Main Street
, NY 12345

我想不通这个问题的原因。 任何帮助将不胜感激,因为我的想法。

c
3个回答
0
投票
#include <stdio.h>

int main(void){
    char address[100];
    char city[100];
    char state[2];
    char zip[15];

    printf("Enter street address: ");
    scanf(" %[^\n]",&address);

    printf("Enter city: ");
    scanf(" %[^\n]",&city);

    printf("Enter state: ");
    scanf(" %s",&state);

    printf("Enter ZIP Code: ");
    scanf(" %s",&zip);

    printf("\nONE: %s\n",address);
    printf("TWO: %s\n",city);
    printf("THREE: %s\n",state);
    printf("FOUR: %s\n",zip);

    return 0;
}

复制粘贴到https://www.codechef.com/ide,你会看到下面的输出:

Enter street address: Enter city: Enter state: Enter ZIP Code: 
ONE: 1 Main Street
TWO: New York City, NY 12345
THREE: 
FOUR: @

您存储而不是在逗号停止在城市的一切。你觉得你的城市scanf函数是干什么的?


0
投票

后续的代码是我的工作站上运行良好。

#include <stdio.h>
int main(void){
    char address[100];
    char city[100];
    char state[2];
    char zip[15];
    printf("Enter street address: ");
    scanf(" %[^\n]",address);
    printf("Enter city: ");
    scanf(" %[^\n]",city);
    printf("Enter state: ");
    scanf(" %s",state);
    printf("Enter ZIP Code: ");
    scanf(" %s",zip);
    printf("%s\n%s, %s %s",address,city,state,zip);
    return 0;
}

0
投票

正如评论和其他答案提到的,你有许多问题。前两个可以立即激活未定义行为是:

  1. 尝试读取状态"NY"作为一个字符串到char state[2];。为了在C有效的字符串,字符必须由一个NUL终止字符终止。这意味着存储2个字符的状态缩写,你需要存储(最小)的3个字符。例如。 {'N', 'Y', '\0'}。 (主@JonathanLeffler推导出state短存储的直接后果如何可能导致'\0'字符将被存储为在city的第一个字符造成city是一个空字符串);
  2. 当阅读与scanf你必须提供一个指向足够的存储你正在阅读的串串。由于address, city, state, zip是字符数组,上访问,它们被转换的指针的第一个字符(参见:C11 Standard - 6.3.2.1 Other Operands - Lvalues, arrays, and function designators(p3))所以作为scanf一个参数,并没有'&'使用时每个已经是一个指针(地址)操作者需要在它们前面参数列表。

其他注意事项,避免在您的代码,除非绝对必要使用魔法数字。 100, 2, 15低于魔法数字。

    char address[100];
    char city[100];
    char state[2];
    char zip[15];

如果您需要在address, city, state, zip字符数恒定,#define为每个或使用全局enum做同样的事情,例如

enum { STSZ = 3, ZIPSZ = 15, CIADDR = 100 };    /* constants */

(注cityaddress都是100,所以单CIADDR常数都行)

当数绝对在你的代码需要?与scanf系列函数读取时,如果提供了一个场宽度调节器,以保护您的数组边界。另外,使用scanf家庭时,必须检查返回,每一次。否则,匹配或输入故障,可能会发生(或用户可以生成一个手动EOF取消输入),你盲目地推进使用未填充可能留下不确定调用未定义行为变量。

把这些拼在一起,并思考着,你可能只是发现自己处理代码中的1个多地址,以下是可以在单个文本行读city, state zip值的示例和值存储在一个结构。 (这允许你声明结构的阵列,或一个指针,并根据需要与一个以上的地址以后处理时分配)

#include <stdio.h>

enum { STSZ = 3, ZIPSZ = 15, CIADDR = 100 };    /* constants */

typedef struct {            /* simple struct presuming in the future */
    char address[CIADDR],   /* you may have more than 1 address */
        city[CIADDR],
        state[STSZ],        /* STSZ must be 3 to read a string of 2-char */
        zip[ZIPSZ];
} loc_t;

int main (void) {

    loc_t location1 = { .address = "" };    /* declare/initialize struct */

    printf ("enter street address: ");      /* prompt/read/validate address */
    if (scanf (" %99[^\n]", location1.address) != 1) {
        fputs ("sscanf() error: invalid address.\n", stderr);
        return 1;
    }

    printf ("enter city: ");                /* prompt/read/validate city */
    if (scanf (" %99[^,],", location1.city) != 1) {
        fputs ("sscanf() error: invalid city.\n", stderr);
        return 1;
    }

    printf ("enter state: ");               /* prompt/read/validate state */
    if (scanf (" %2s", location1.state) != 1) {
        fputs ("sscanf() error: invalid state.\n", stderr);
        return 1;
    }

    printf ("enter zip: ");                 /* prompt/read/validate zip */
    if (scanf (" %14s,", location1.zip) != 1) {
        fputs ("sscanf() error: invalid zip.\n", stderr);
        return 1;
    }

    /* output results preceeded by 2-newlines */
    printf ("\n\n%s\n%s, %s %s\n", location1.address, location1.city,
            location1.state, location1.zip);
}

(注意:数字为场宽度改性剂包括在每个scanf调用保护你的数组边界另外多个'\n'输出补偿了未使用的提示之前时city, state zip是所有在"city: "提示输入。)

实施例使用/输出

进入"New York City, NY 12345"截至"enter city: "提示一个字符串:

$ ./bin/readaddr
enter street address: 1 Main Street
enter city: New York City, NY 12345
enter state: enter zip:

1 Main Street
New York City, NY 12345

在寻找的东西,让我知道,如果你还有其他问题。

© www.soinside.com 2019 - 2024. All rights reserved.