一个特定的变量引用被跳过

时间:2019-02-12 05:07:13

标签: c

最后%s中的printf似乎已被完全跳过。

这是完整的代码:

#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

我无法弄清楚这个问题的原因。 任何帮助将不胜感激,因为我没有主意。

3 个答案:

答案 0 :(得分: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: @

您正在将所有内容存储在城市中,而不是停在逗号前。您认为您对城市的了解如何?

答案 1 :(得分: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;
}

答案 2 :(得分:0)

如评论和其他答案中所述,您有很多问题。立即调用未定义行为的前两个是:

  1. 尝试将状态"NY"作为字符串读取到char state[2];中。要在C中成为有效的字符串,字符必须以 nul-termination 字符终止。意思是要存储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常量)

您的代码中何时绝对需要数字?当提供{e​​m> field-width 修饰符来保护数组边界时,使用scanf函数系列进行读取时。此外,在使用scanf系列产品时,您 必须每次检查退货 。否则会发生 matching input 失败(或者用户可以生成手册EOF来取消输入),并且您盲目地使用不是'填充并且可能不确定地调用未定义行为

将这些部分放在一起,并考虑到您可能发现自己在代码中处理了多个地址,下面的示例可以在一行文本中读取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调用中都包含

注意:)用于 field-width 修饰符的数字,以保护数组边界。此外,还需要多个{{1} },当'\n'提示符下都输入了city, state zip时,输出将补偿未使用的提示符)

使用/输出示例

"city: "提示符下输入"New York City, NY 12345"作为一个字符串:

"enter city: "

仔细检查一下,如果还有其他问题,请告诉我。