scanf 更改其他字符串的值
scanf changes values from other strings
我主要用 Java 开发软件,但目前我正在用 C 尝试一些东西,但遇到了一个奇怪的问题。
我使用 scanf()
方法更改字符串的值,但是 scanf()
不仅更改参数化字符串的值,它还更改其他字符串的值。
现在我的问题是:我是不是被开发人员友好的 Java 宠坏了,我太笨了,无法正确使用它?我不明白我哪里做错了。
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
char lFileType[] = ".txt";
char lFilePath[] = "C:\Notenverwaltungssystem";
char lFileFinalPath[] = "";
char lFileName[] = "";
printf( "lFileType before scanf: " );
printf( "%s \n", lFileType );
printf( "lFilePath before scanf: " );
printf( "%s \n", lFilePath );
printf( "lFileName before scanf: " );
printf( "%s \n", lFileName );
printf( "lFileFinalPath before scanf: " );
printf( "%s \n\n", lFileFinalPath );
printf( "Bitte geben Sie den Namen der Pruefung an: \n\n" );
scanf( "%s", &lFileName );
printf( "\nlFileType after scanf: " );
printf( "%s \n", lFileType );
printf( "lFilePath after scanf: " );
printf( "%s \n", lFilePath );
printf( "lFileName after scanf: " );
printf( "%s \n", lFileName );
printf( "lFileFinalPath after scanf: " );
printf( "%s \n\n", lFileFinalPath );
system("PAUSE");
return 0;
}
预期输出:
lFileType before scanf: .txt
lFilePath before scanf: C:\Notenverwaltungssystem
lFileName before scanf:
lFileFinalPath before scanf:
Bitte geben Sie den Namen der Pruefung an:
Test
lFileType after scanf: .txt
lFilePath after scanf: C:\Notenverwaltungssystem
lFileName after scanf: Test
lFileFinalPath after scanf:
Press any key to continue . . .
执行程序时得到的输出:
lFileType before scanf: .txt
lFilePath before scanf: C:\Notenverwaltungssystem
lFileName before scanf:
lFileFinalPath before scanf:
Bitte geben Sie den Namen der Pruefung an:
Test
lFileType after scanf: .txt
lFilePath after scanf: st
lFileName after scanf: Test
lFileFinalPath after scanf: est
Press any key to continue . . .
当你这样定义一个字符串时:
char lFileName[] = "";
它只分配了一个字节(用于终止'[=15=]'
)。相当于:
char lFileName[1] = "";
如果您尝试通过 scanf
将某些内容读入此字符串,则会出现缓冲区溢出。
将此(和类似定义)更改为例如
char lFileName[PATH_MAX] = "";
(请注意,您可能需要在程序开始附近使用 #include <limits.h>
才能获得 PATH_MAX
的定义)。
还有一点:将字符串传递给 scanf
时,您不需要取消引用它,因此:
scanf( "%s", &lFileName );
应该是:
scanf( "%s", lFileName );
(对于诸如 int
或 float
之类的简单标量类型,您确实需要将指针传递给变量,这对于 C 的新手来说可能会造成混淆。)
你所有的数组都定义了与提供的初始化字符串相同的大小。所以,基本上,
char lFileFinalPath[] = "";
char lFileName[] = "";
长度为 1,这是您不想要的。如果您希望数组在程序的后面部分保持不同的长度,您可能需要明确提供大小。
此外,尽可能通过数组大小限制 scanf()
输入始终被认为是一种好习惯,例如对于定义为
的数组
char lFileType[128] = {0};
你应该使用 scanf()
格式
scanf("%127s", lFileType);
以避免因较长的输入而导致缓冲区溢出的可能性。
char lFileName[] = "";
这只是分配了 1 个字节的内存(用于空字符'\0'),因为您没有指定数组的大小。 scanf 函数尝试将用户输入的字符串存储在数组边界之外,从而导致 运行 时间错误。
#define FILE_LEN 64;//select a size suitable for you.
char lFileName[FILE_LEN] = "";
另一种方法是使用 malloc() 或 calloc() 动态分配内存。
char *lFileName = NULL;
lFileName = calloc(FILE_LEN,1);
并且永远记得在使用 free() 后释放动态分配的内存。否则可能会导致内存泄漏。
free(lFileName);
我主要用 Java 开发软件,但目前我正在用 C 尝试一些东西,但遇到了一个奇怪的问题。
我使用 scanf()
方法更改字符串的值,但是 scanf()
不仅更改参数化字符串的值,它还更改其他字符串的值。
现在我的问题是:我是不是被开发人员友好的 Java 宠坏了,我太笨了,无法正确使用它?我不明白我哪里做错了。
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
char lFileType[] = ".txt";
char lFilePath[] = "C:\Notenverwaltungssystem";
char lFileFinalPath[] = "";
char lFileName[] = "";
printf( "lFileType before scanf: " );
printf( "%s \n", lFileType );
printf( "lFilePath before scanf: " );
printf( "%s \n", lFilePath );
printf( "lFileName before scanf: " );
printf( "%s \n", lFileName );
printf( "lFileFinalPath before scanf: " );
printf( "%s \n\n", lFileFinalPath );
printf( "Bitte geben Sie den Namen der Pruefung an: \n\n" );
scanf( "%s", &lFileName );
printf( "\nlFileType after scanf: " );
printf( "%s \n", lFileType );
printf( "lFilePath after scanf: " );
printf( "%s \n", lFilePath );
printf( "lFileName after scanf: " );
printf( "%s \n", lFileName );
printf( "lFileFinalPath after scanf: " );
printf( "%s \n\n", lFileFinalPath );
system("PAUSE");
return 0;
}
预期输出:
lFileType before scanf: .txt
lFilePath before scanf: C:\Notenverwaltungssystem
lFileName before scanf:
lFileFinalPath before scanf:
Bitte geben Sie den Namen der Pruefung an:
Test
lFileType after scanf: .txt
lFilePath after scanf: C:\Notenverwaltungssystem
lFileName after scanf: Test
lFileFinalPath after scanf:
Press any key to continue . . .
执行程序时得到的输出:
lFileType before scanf: .txt
lFilePath before scanf: C:\Notenverwaltungssystem
lFileName before scanf:
lFileFinalPath before scanf:
Bitte geben Sie den Namen der Pruefung an:
Test
lFileType after scanf: .txt
lFilePath after scanf: st
lFileName after scanf: Test
lFileFinalPath after scanf: est
Press any key to continue . . .
当你这样定义一个字符串时:
char lFileName[] = "";
它只分配了一个字节(用于终止'[=15=]'
)。相当于:
char lFileName[1] = "";
如果您尝试通过 scanf
将某些内容读入此字符串,则会出现缓冲区溢出。
将此(和类似定义)更改为例如
char lFileName[PATH_MAX] = "";
(请注意,您可能需要在程序开始附近使用 #include <limits.h>
才能获得 PATH_MAX
的定义)。
还有一点:将字符串传递给
scanf
时,您不需要取消引用它,因此:
scanf( "%s", &lFileName );
应该是:
scanf( "%s", lFileName );
(对于诸如 int
或 float
之类的简单标量类型,您确实需要将指针传递给变量,这对于 C 的新手来说可能会造成混淆。)
你所有的数组都定义了与提供的初始化字符串相同的大小。所以,基本上,
char lFileFinalPath[] = "";
char lFileName[] = "";
长度为 1,这是您不想要的。如果您希望数组在程序的后面部分保持不同的长度,您可能需要明确提供大小。
此外,尽可能通过数组大小限制 scanf()
输入始终被认为是一种好习惯,例如对于定义为
char lFileType[128] = {0};
你应该使用 scanf()
格式
scanf("%127s", lFileType);
以避免因较长的输入而导致缓冲区溢出的可能性。
char lFileName[] = "";
这只是分配了 1 个字节的内存(用于空字符'\0'),因为您没有指定数组的大小。 scanf 函数尝试将用户输入的字符串存储在数组边界之外,从而导致 运行 时间错误。
#define FILE_LEN 64;//select a size suitable for you.
char lFileName[FILE_LEN] = "";
另一种方法是使用 malloc() 或 calloc() 动态分配内存。
char *lFileName = NULL;
lFileName = calloc(FILE_LEN,1);
并且永远记得在使用 free() 后释放动态分配的内存。否则可能会导致内存泄漏。
free(lFileName);