最后%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
我无法弄清楚这个问题的原因。
任何帮助将不胜感激,因为我没有主意。
答案 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)
如评论和其他答案中所述,您有很多问题。立即调用未定义行为的前两个是:
"NY"
作为字符串读取到char state[2];
中。要在C中成为有效的字符串,字符必须以 nul-termination 字符终止。意思是要存储2个字符的状态缩写,您需要3个字符的存储(最小)。例如。 {'N', 'Y', '\0'}
。 (主@JonathanLeffler推断出state
短存储的直接后果如何导致'\0'
字符作为第一个字符存储在city
中,从而导致city
为空字符串); 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 */
(注释 city
和address
均为100
,因此只需一个CIADDR
常量)
您的代码中何时绝对需要数字?当提供{em> 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: "
仔细检查一下,如果还有其他问题,请告诉我。