0

I attempt to copy the contents of closure in res using strcpy, however i get what i think are soome garbage values before what actually is in closure, any ideas on how to solve this issue, all help is appreciated :) . Please ignore the rest of the scuffed code.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main()
{
    int fdcount;
    int i, j;

    char closure[100];
    char temp[20];
    printf("nb fd: \n");
    scanf("%d", &fdcount);
    char left[fdcount][100];
    char right[fdcount][100];
    char res[fdcount][100];

    for (i = 0; i < fdcount; i++) {
        printf("left of fd %d: ", i + 1);
        scanf(" %c", temp);
        strcpy(left[i], temp);
        printf("right of fd %d: ", i + 1);
        scanf(" %c", temp);
        strcpy(right[i], temp);
    }
    printf("closure ");
    scanf(" %c", closure);

    //system("cls");
    printf("your fds \n");
    for (i = 0; i < fdcount; i++) {
        printf("%s -> %s \n", left[i], right[i]);
    }

    strcpy(closure, res[0]);
    for (i = 0; i < fdcount; i++) {
        printf(" %s", res[i]);
    }

    return 0;
}
mch
  • 9,424
  • 2
  • 28
  • 42
Pung
  • 25
  • 6
  • 2
    `scanf(" %c",temp);` getting a byte on to `temp[0]` it is not entire string where you can pass it `strcpy` – TruthSeeker Mar 21 '22 at 13:17
  • 1
    Either the wrong format type, or the wrong data type. I guess you want `scanf("%19s", temp);` as you pass the input to `strcpy`. Aside: why are all the arrays length `100` when you can only input to length `20`? – Weather Vane Mar 21 '22 at 13:24
  • You never set `res`m so of course it contains garbage. You can use `memset` to clear it, but it doesn'y seem you are actually using it for anything. – SGeorgiades Mar 21 '22 at 13:32
  • Side note: Your code would be easier for yourself and other people to read if you used proper indentation. Someone else has edited the code in the question for you, in order to fix the indentation. Isn't the code much easier to read now, as you can now see at a glance where the loops start and end? – Andreas Wenzel Mar 21 '22 at 13:39
  • 1
    Please [edit] and show a simpe example if input and expected output. – Jabberwocky Mar 21 '22 at 13:39
  • Yes – note that `%s` won't work if the inputs have any whitespace. – Weather Vane Mar 21 '22 at 13:50
  • @mch Please don't encourage horribly formatted questions by spoon feeding free formatting. The OP needs to learn never to post such questions and if you do all the work for them, they never will. – Lundin Mar 21 '22 at 14:01
  • @Lundin: On the other hand, fixing the formatting of the code in the question will demonstrate to the poster that their code is much more readable with these changes, and it could encourage them to take over these changes and also to use proper formatting in future code. – Andreas Wenzel Mar 21 '22 at 14:08
  • @AndreasWenzel Proper code formatting is taught in the very first lessons in any programming class. The purpose of this site is not to teach the utter basics of programming to laymen, but to give advise to enthusiast or professional programmers. Programmer = someone who at least holds a bare minimum of knowledge about the programming language used. Contrary to popular belief, SO was never an "ask a programmer" site for laymen. It has always been an "ask another programmer" site. – Lundin Mar 21 '22 at 14:15

1 Answers1

0

The line

strcpy(closure, res[0]);

will copy the string in res[0] to closure.

You probably want to do the opposite. You want to copy the string in closure to res[0]. In that case, you should swap the two arguments, by changing the line to the following:

strcpy( res[0], closure );

Another problem is that using the function strcpy requires the second argument to actually be a string (i.e. a sequence of characters terminated by a null character). If it is not, then your program will be invoking undefined behavior (i.e. your program may crash).

The content of closure is not a string, because the line

scanf(" %c", closure);

will only write a single character to closure. It won't write a terminating null character afterwards.

If you want to make closure a valid string, then all you have to do is add a terminating null character after the character, like this:

closure[1] = '\0';

On the other hand, if you want to read a whole line of input as a string, then you could use the function fgets instead:

fgets( closure, sizeof closure, stdin );

Note that the function fgets will also read the newline character at the end of the line, and store it as part of the string. If you do not want this, see the following question for different possibilities on how to remove this newline character:

Removing trailing newline character from fgets() input

Another problem in your code is that the following loop is wrong:

for (i = 0; i < fdcount; i++) {
    printf(" %s", res[i]);
}

When using printf with the %s conversion format specifier, the argument must be a valid null-terminated string. Since you are calling printf in a loop, the contents of res[0] up to res[fdcount-1] must contain valid strings. However, even after making the fixes mentioned above, only res[0] will be a valid string with a null terminating character. The content of res[1] to res[fdcount-1] will still contain garbage data. Therefore, you should not attempt to treat this garbage data as strings, because doing so will invoke undefined behavior.

Here is a short demonstration program which reads a line of input into closure, copies it, and then prints the copy:

#include <stdio.h>
#include <string.h>

int main( void )
{
    int fdcount = 20;
    char closure[100];
    char res[fdcount][100];

    //prompt user for input
    printf( "Please enter a line of input: " );

    //read one line of user input
    fgets( closure, sizeof closure, stdin );

    //remove newline character from input
    closure[strcspn(closure,"\n")] = '\0';

    //copy input to res[0]
    strcpy( res[0], closure );

    //print copy
    printf( "Contents of res[0]: %s\n", res[0] );
}

This program has the following behavior:

Please enter a line of input: This is a test.
Contents of res[0]: This is a test.

Of course, it does not make much sense to create an array of strings, if you are only using one string.

Here is the same program with full error checking:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main( void )
{
    int fdcount = 20;
    char closure[100];
    char res[fdcount][100];
    char *p;

    //prompt user for input
    printf( "Please enter a line of input: " );

    //attempt to read one line of user input
    if ( fgets( closure, sizeof closure, stdin ) == NULL )
    {
        fprintf( stderr, "Input error!\n" );
        exit( EXIT_FAILURE );
    }

    //verify that input buffer was large enough to store entire line
    p = strchr( closure, '\n' );
    if ( p == NULL )
    {
        if ( !feof( stdin ) )
        {
            fprintf( stderr, "Line too long to fit into buffer!\n" );
            exit( EXIT_FAILURE );
        }
    }
    else
    {
        //remove newline character from input
        *p = '\0';
    }

    //copy input to res[0]
    strcpy( res[0], closure );

    //print copy
    printf( "Contents of res[0]: %s\n", res[0] );
}

Please ignore the rest of the scuffed code.

The rest of your code is hard to ignore, because it is also invoking undefined behavior, so that the behavior of your entire program is undefined (i.e. your program may crash).

The lines

strcpy(left[i], temp);

and

strcpy(right[i], temp);

require temp to be a string, which it is not, because it is not terminated by a null character.

Andreas Wenzel
  • 22,760
  • 4
  • 24
  • 39