0

I need to create a string of arrays from a string input in different iterations. This string of arrays will be passed to a separate function in each iteration. The string input will be of the form 'A a,b,c,d,e,f,g,h' , basically 'A' followed by 8 comma separated string values. The code I wrote for this is -

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

int main() {

    while (1) {

        char x[100];
        fgets(x, sizeof(x), stdin);  // read string

        if (x[0] == 'A') {

            int k = 2;       // index of 1st required value
            char temp[8][25];

            for (int i = 0; i < 8; i = i + 1) {

                int temp2 = k;
                while ((x[k] != ',') && (x[k] != '\n')) { 

                    k = k + 1;            // find no. of characters in one particular  value
                }
                strncpy(temp[i], &x[temp2], k - temp2); // copy required characters into temp
                k = k + 1;
            }
            printf("%s",temp[0]);
        }
        else break;
    }
    return 0;
}

Problems-

1 - If I input 'A a,a,a,a,a,a,a,a' then temp[0] stores 'a~j' or some other random characters after the a. These random characters pop up in other temps too for different input strings (in Codeblocks)

2 - If in one iteration input is 'A abc,a,a,a,a,a,a,a' and in second it is 'A fg,a,a,a,a,a,a,a' then temp[0] goes from 'abc' to 'fgc' instead of 'fg' (Codeblocks)

Codeblocks and Visual Studio printed quite different strings in the print statement. Is it possible to deal with these problems so that I have a string of arrays in each iteration depending on the string input? Does the problem lie with strncpy? Is malloc a better way? Any help is appreciated.

Nimish
  • 5
  • 3
  • Please read the [documentation of strncpy](https://en.cppreference.com/w/c/string/byte/strncpy) *very closely*. It does not do what you think it does when the limit (third argument) is reached (as is the case in your program) -- your destination *will not hold a valid string* as there will be no terminator. `strncpy` is unfortunately surprising in this regard. (Not an answer as I stopped checking for further problems after I saw the `strncpy` in there.) – DevSolar Mar 08 '22 at 13:15
  • Not many standard functions are "surprising". But `strncpy` is, `*scanf` can be, `strtok` is funny when it comes to multiple separators and empty fields, and `fgets` keeps the newline in there, but you realized that already. (Note that the *existence* of that newline tells you if you're looking at a complete line, or a partial one because the line was longer than your buffer.) – DevSolar Mar 08 '22 at 13:30
  • It's the kind of arcane knowledge you pick up when attempting to *implement* the standard library. Some things become clearer, some things get discovered, and some things turn out to be out of the realm of "OMFG how did anybody get this to work properly, *ever*..." :-D – DevSolar Mar 08 '22 at 13:37
  • 1
    That said, that is addressible by: `temp[i][k - temp2] = 0;` after the `strncpy`. However, fair warning: this code is highly assumptive in the first place. It assumes no string line will *ever* exceed 98 characters + newline, + terminator. It assumes *all* lines will end with a newline. It assumes no string of extraction will *ever* exceed 24 characters + terminator. As soon as *any* of those assumptions are violated by the incoming data the code plunges into *undefined behavior*. – WhozCraig Mar 08 '22 at 13:45
  • This is for an assignment so I guess I made that assumption. But if it was not, would there be a fool-proof way to do this such as using malloc? @WhozCraig – Nimish Mar 08 '22 at 13:51
  • Either making the string bed dynamic or enforcing the size restrictions and aborting the operation in some form, or combination of the two. Regardless of the method, care should be taken to ensure no assumptions lead to UB is important. If you think about it, as an example, conceptually this task is doable reading *one* character at a time from the input stream. Not saying do that (depending on the authoritarian tendencies of your academia), but more a thought experiment. Think about how one would have to do that, and how you would guard against overruns, etc. Food for the gray matter. – WhozCraig Mar 08 '22 at 13:57
  • Use `strdup`. It will soon be in the standard and it's available basically everywhere. – rici Mar 08 '22 at 15:27

0 Answers0