我得到了以下。
my-app.c
文件:
char username[USERNAME_MAX_LEN] = "\0"; char password[PASSWORD_MAX_LEN] = "\0"; scanf("%s %s", username, password); printf("username-len: %ld, password-len: %ld\n", strlen(username), strlen(password));
credentials.data
文件:
jdons f4$dsef35fs
所以:
$ ./my-app < credentials.data username-len: 0, password-len: 0
和:
$ cat credentials.data | ./my-app username-len: 5, password-len: 10
scanf()
能够以相同的方式处理这两种情况? Barankin,
嗯…这是一个有趣的行为。
标准输入间接技术的工作(如预期)对我来说…
landkrc@lasun175:/home/user/landkrc/crap $ cat lg.c #include <stdio.h> #include <strings.h> #define USERNAME_MAX_LEN 36 #define PASSWORD_MAX_LEN 36 int main(int argc, char *argv[]) { printf("Hello, world\n"); char username[USERNAME_MAX_LEN]; char password[PASSWORD_MAX_LEN]; *username = 0; *password = 0; scanf("%s %s", username, password); printf("username-len: %ld, password-len: %ld\n", strlen(username), strlen(password)); return 0; } landkrc@lasun175:/home/user/landkrc/crap $ cc -V cc: Sun C 5.8 2005/10/13 usage: cc [ options] files. Use 'cc -flags' for details landkrc@lasun175:/home/user/landkrc/crap $ cc -o lg lg.c landkrc@lasun175:/home/user/landkrc/crap $ echo '12345678 1234567890 > ' >data.txt landkrc@lasun175:/home/user/landkrc/crap $ lg <data.txt username-len: 8, password-len: 10 landkrc@lasun175:/home/user/landkrc/crap $ cat data.txt | lg username-len: 8, password-len: 10
也许你只需要在你的credentials.data
文件末尾加一个行尾字符?
干杯。 基思。
这一行:
scanf("%s %s", username, password);
本质上是不安全的(除非你完全控制程序的标准输入内容)。 "%s"
格式表示读取任意长度的非空白字符序列。 不管长时间的目标数组是多长,一个足够长的单词(例如,由你的猫坐在键盘上引起的)将会溢出。
您可以使用长度修饰符来限制输入的大小。 例如(未经测试):
scanf("%36s %36s", username, password);
或更好:
scanf("%*s, %*s", USERNAME_MAX_LEN, username, PASSWORD_MAX_LEN, password);
但是最好使用fgets()
来读取整行,然后使用sscanf()
来读取行。
而printf
调用中可能存在一个问题:
printf("username-len: %ld, password-len: %ld\n", strlen(username), strlen(password));
strlen()
返回size_t
类型的结果,但是"%ld"
需要long int
类型的参数。 如果你的系统支持它,你可以使用"%zu"
打印size_t
类型的值,但这不是100%的可移植性。 或者你可以将size_t
值转换为unsigned long:
printf("username-len: %lu, password-len: %lu\n", (unsigned long)strlen(username), (unsigned long)strlen(password));
有可能,但不太可能,这可能会导致非零的size_t
值显示为0。
检查你的credentials.data是否在最后包含换行符? cat命令将自动附加到文件的最后一行之后。
就像我尝试的那样,我无法像你一样重现同样的问题。 我甚至手动从credentials.data
文件中删除行字节的结尾,它仍然正常工作(因为它应该)。 你正在运行什么版本的Linux或shell?