0

UPDATE: There are essentially two issues here:

  1. How to pass an array of strings to and access them inside a function. (This is solved by Is 2d array a double pointer?
  2. How to do this when the length of the array is variable. Using C99 compliant compiler vs Visual Studio MSVC compiler.

The answer to point 2 is:

MSVC compiler currently does not allow the array length to be set as a parameter in the function signature as below although this would be OK with a C99 compliant compiler.

void ReadItems(FILE * pFile, size_t numBytes, char stringArrayOut[][numBytes+1], int numberOfItems)

To make it work in VS 2015 I copied the pointer and incremented to the next string manually using pointer arithmetic:

void ReadItems(FILE * pFile, size_t numBytes, char * ptr_stringArrayOut, int numberOfItems)
{
    char * ptr_nextString = ptr_stringArrayOut;

    for (int i = 0; i < numberOfItems; i++) {
        ReadItem(pFile, numBytes, ptr_nextString);
        if (i >= numberOfItems - 1) break;
        ptr_nextString += numBytes;
    }
}

What is the correct way to create an array of empty C strings, pass them to a function and have the function fill the strings?

In my usecase I want to read some strings from a file and put them into the array.

Inside ReadItem function I read the text from the file successfully into readBuff, but when I try to copy the string into stringOut I get the error Access violation writing location 0x00000000..

How can I make this work?

int main(void){

    /* Declare and initialize an array of 10 empty strings, each string can be 
    up to 16 chars followed by null terminator ('\0') hence length = 17. */

    char myArrayOfStrings[10][17] = { "","","","","","","","","","" };

    //Open file
    FILE *pFile = fopen("C:\\temp\\somefile.ext", "r");
    if (pFile == NULL) { printf("\nError opening file."); return 2; }

    // myArrayOfStrings should contain 10 empty strings now.

    ReadItems(pFile, 16, myArrayOfStrings, 10);

    // myArrayOfStrings should now be filled with the strings from the file.
}

void ReadItems(FILE * pFile, size_t numBytes, char **stringArrayOut, int numberOfItems)
{
    for (int i = 0; i < numberOfItems; i++) {
        ReadItem(pFile, numBytes, stringArrayOut[i]);
    }
}

void ReadItem(FILE * pFile, size_t numBytes, char * stringOut){
    int numBytesRead = 0;
    char readBuff[201] = { 0 };
    if (numBytes > 200) numBytes = 200;
    numBytesRead = fread (readBuff, 1, numBytes, pFile);
    strcpy(stringOut, readBuff); /* ERROR: Access violation writing location 0x00000000. */
    printf("\n# bytes: %d \t", numBytesRead);
    printf("%s", numBytes, stringOut);
}
Community
  • 1
  • 1
  • 2
    2D arrays are not double pointers. For example, if you had used `char stringArrayOut[][17]` instead of `char **stringArrayOut` in the arguments for `ReatItems()`, it'd work. – Dmitri Jul 22 '16 at 03:35
  • Yes using `char stringArrayOut[][17]` as the argument works. @Dmitri what if I want to deal with different size strings not just 17 length? What would be the best way to do this? The compiler wont allow `char stringArrayOut[][]' without specifying the length in the second square brackets. –  Jul 22 '16 at 04:10
  • With c99+, you can use another argument (say, `int n`) to specify the inner dimension, and use `char stringArrayOut[][n]`. – Dmitri Jul 22 '16 at 04:13
  • @Dmitri if I try to write the function signature as `ReadItems(FILE * pFile, size_t numBytes, char stringArrayOut[][n], int n, int numberOfItems)` that gives compile error identifier 'n' is undefined. –  Jul 22 '16 at 04:39
  • Either put `n` before `stringArrayOut`, or forward declare it (add an extra `int n;` at the start of the argument list). Or use `numBytes` instead, like: `void ReadItems(FILE * pFile, size_t numBytes, char stringArrayOut[][numBytes+1], int numberOfItems)`, if `numBytes` is always 1 less than the inner dimension. – Dmitri Jul 22 '16 at 04:42
  • I'm using MS Visual Studio 2015 with MSVC compiler which it seems does not permit array length dimensions to be set with function arguments I think because MSVC does not fully implement the C99 standard, hence I can't do `char stringArrayOut[][n]` in the function signature :-( –  Jul 22 '16 at 06:09

0 Answers0