scanf更改其他字符串的值

时间:2015-10-02 07:28:44

标签: c arrays scanf

我主要使用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 . . .

3 个答案:

答案 0 :(得分:7)

定义这样的字符串时:

char lFileName[] = "";

它只分配了一个字节(用于终止'\0')。它相当于:

char lFileName[1] = "";

如果您尝试通过scanf读取此字符串中的内容,则会出现缓冲区溢出。

将此(及类似定义)更改为例如

char lFileName[PATH_MAX] = "";

(请注意,在progaram开头附近可能需要#include <limits.h>才能获得PATH_MAX的定义。

<小时/> 还有一点:将字符串传递给scanf时,您无需取消引用它,因此:

scanf( "%s", &lFileName );

应该是:

scanf( "%s", lFileName );

(对于简单的标量类型,例如intfloat,但是您需要传递一个指向变量的指针,这对于C新手来说可能会造成混淆。)

答案 1 :(得分:4)

所有数组的定义大小与提供的初始化字符串相同。所以,基本上,

char lFileFinalPath[] = "";
char lFileName[] = "";

长度为1,这是你不想要的。如果希望数组在程序的后续部分保持不同的长度,则可能需要显式提供大小。

此外,在任何可能的情况下,将scanf()输入限制为数组大小始终被认为是一种好习惯,例如像

这样定义的数组
char lFileType[128] = {0};

您应该使用scanf()格式

scanf("%127s", lFileType);

以避免较长输入导致缓冲区溢出的可能性。

答案 2 :(得分:2)

char lFileName[] = ""; 

这只是分配1个字节的内存(对于null charecter&#39; \ 0&#39;),因为你没有指定数组的大小。 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);