-1

So I've tried nearly all solutions for similar questions and neither of them worked. I have a string which looks like the following:

AAAA BBBBBBBBBBBB CCCCCCC 15
  %s           %s      %s %d

I've so far tried it like:

sscanf(str, "%s %s %s %d", ...); 

It did not work the first %s ate the ' ' also and all went wrong. After that i tried like:

sscanf(str, "%6[^ ] %30[^ ] %8[^ ] %d[^\n]", ...);

The same thing happens. How can i split the parts of this string with sscanf?

Edit: The result should go in a struct. The current code looks like:

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

typedef struct sor {
    char npkod[6];
    char nev[30];
    char tkod[8];
    int jegy;
} SOR;

double work(char* fnev, char* tkod)
{
    FILE * fp;
    char aktualis_sor[127] = { 0 };
    SOR beolvasott_sor;
    double atlag = 0.0;
    int ossz = 0;
    int db = 0;

    fp = fopen(fnev, "rb");
    if(fp == NULL)
    {
        printf("Fajl nem talalhato.\n");
        return -1;
    }

    while(fgets(aktualis_sor, 127, fp))
    {
        sscanf(aktualis_sor, "%6[^ ] %30[^ ] %8[^ ] %d", beolvasott_sor.npkod, beolvasott_sor.nev, beolvasott_sor.tkod, &beolvasott_sor.jegy);
        printf("%s %s %s %d\n\n\n", beolvasott_sor.npkod, beolvasott_sor.nev, beolvasott_sor.tkod, beolvasott_sor.jegy);

        if(strcmp(beolvasott_sor.tkod, tkod) == 0)
        {
            ossz += beolvasott_sor.jegy;
            ++db;
        }
    }

    fclose(fp);

    atlag = (double)ossz / (double)db;

    return atlag;
}

int main(void)
{
    printf("Atlag: %f\n", work("tan.txt", "INDK1010"));
    return 0;
}

And here's the actual problem: Original: AAA111 Harminckarakteresnevaaaaaaaaaa INDK1010 5

printf after sscanf: AAA111HarminckarakteresnevaaaaaaaaaaINDK1010♣ HarminckarakteresnevaaaaaaaaaaINDK1010♣ INDK1010♣ 5

Wrath
  • 673
  • 9
  • 32
  • 3
    See http://stackoverflow.com/questions/2091815/how-to-split-string-to-tokens-in-c for using `strchr` instead of `sscanf` – Drew McGowen Jun 27 '13 at 21:34
  • 1
    Show more (and compilable) example code. These `sscanf()` calls work fine for me when passed in reasonable arguments for where to place the parsed data. I suspect you might be passing in bogus pointers or buffers that are too small. – Michael Burr Jun 27 '13 at 21:41
  • @Joey Egyetemi feladat? Neptun ("npkod")? :D Better use `strchr()` and/or `strtok_r()`. Also, `const`-qualify your input arguments. –  Jun 27 '13 at 21:56
  • 1
    It should ensure the area for the C string termination character('\0'). E.g. for AAA111 `char npkod[7];` – BLUEPIXY Jun 27 '13 at 21:56

2 Answers2

2

You are writing past the end of your string buffers.

When given a conversion spec like "%6[^ ]". the scanf() family of functions will read up to 6 characters from the stream (or string in this case) to put into the specified buffer. Then it will null terminate the buffer - so your buffer needs to be at least one character larger than the length specification you provide.

Michael Burr
  • 333,147
  • 50
  • 533
  • 760
0

Thanks to Michael Burr, I knew that the only problem was:

Make the char arrays large enough to store a '\0' also.

char xxx[6];

"AAA111" with %6[^ ] how would 7 bytes fit into 6 bytes?
halfer
  • 19,824
  • 17
  • 99
  • 186
Wrath
  • 673
  • 9
  • 32