Rony Schmied
Rony Schmied

Reputation: 31

scanf changes values from other strings

I mainly develop software in Java, but currently I'm trying some stuff in C and I got stuck on a strange problem.

I use the scanf() method to change the value from a string, but scanf() doesn't change just the value from the parameterized string it changes also the value from other strings.

Now my question: am I just spoiled from the developer-friendly Java and I'm too dumb to use it right? I don't see where I'm doing the mistake.

#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;
}

Expected output:

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 . . .

What I get as output when I execute the programm:

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 . . .

Upvotes: 1

Views: 1972

Answers (3)

Paul R
Paul R

Reputation: 212979

When you define a string like this:

char lFileName[] = "";

it only has one byte allocated to it (for the terminating '\0'). It is equivalent to this:

char lFileName[1] = "";

If you try to read something into this string via scanf then you will get a buffer overflow.

Change this (and similar definitions) to e.g.

char lFileName[PATH_MAX] = "";

(Note that you may need #include <limits.h> near the start of your progaram in order to get the definition of PATH_MAX).


One further point: when passing a string to scanf you don't need to dereference it, so:

scanf( "%s", &lFileName );

should just be:

scanf( "%s", lFileName );

(For simple scalar types such as int or float however you do need to pass a pointer to the variable, which can be confusing for people who are new to C.)

Upvotes: 8

Sreeyesh Sreedharan
Sreeyesh Sreedharan

Reputation: 793

char lFileName[] = ""; 

This simply allocate 1 byte of memory(for the null charecter '\0'), since you have not specified the size of the array. The scanf function try to store the user input string beyond the array boundary, leading to run time errors.

#define FILE_LEN  64;//select a size suitable for you.
char lFileName[FILE_LEN] = "";

Another way is to dynamically allocate memory using malloc() or calloc().

char *lFileName = NULL;
lFileName = calloc(FILE_LEN,1);

And always remember to free the dynamically allocated memory after its usage using free(). Otherwise it may lead to memmory leaks.

free(lFileName);

Upvotes: 2

Sourav Ghosh
Sourav Ghosh

Reputation: 134346

All your arrays are defined with a size same as the supplied initializer string. So, essentially,

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

are having length 1, which is what you don't want. You may want to supply the size explicitly, if you want the arrays to hold a different length at a later part of the program.

Also, it is always considered a good practice to limit the scanf() input by the array size, wherever possible, like for an array defined like

char lFileType[128] = {0};

you should use a scanf() format

scanf("%127s", lFileType);

to avoid the possibility of buffer overflow by lengthier inputs.

Upvotes: 4

Related Questions