1

I'm trying to make a program which gets inputs from txt file (coordinates like x1,x2) and store it on element to write in SVG format. The code I wrote below works actually. The problem is when I get input bigger than 16kb, while writing on svg file application crashes. So I cannot find the problem actually. It should be about "strcat(str_joined, svg[i].xy);" this since I'm joining so much string into one string variable.

Input Example :

339, 52
339, 52
339, 52
338, 53
338, 53
337, 54
337, 54
337, 54
337, 55
337, 55
336, 56
336, 56
336, 56
336, 57
335, 57
335, 56
334, 56
334, 56
333, 56
332, 56
332, 56
331, 56
331, 56
330, 56
330, 56
329, 56

Output Example : <svg><polyline points='339,52 339,52 339,52 338,53 338,53 337,54 '/></svg>

And Code : I just put the generate_svg part of the code.

void generate_svg(char *input, char *output)
{         
    //INPUT OPERATİONS //

FILE *fp;
int array_size = 0, i=0, max_lines = 0;  // Line counters
char c;  // To store a character read from file to check whether newline or not
char *str_joined = NULL;

// Open the file
fp = fopen(input, "r");

//Count the number of lines for the array size 
for (c = getc(fp); c != EOF; c = getc(fp))
    if (c == '\n') 
        array_size = array_size + 1;
fclose(fp);


// read the file into an array of coordinates
Coord *coord = malloc(array_size * sizeof *coord); //preallocation for performance
fp = fopen(input, "r");
while(!feof(fp))
{
   //check whether input getting correctly             
   if(fscanf(fp, "%d, %d", &coord[i].x, &coord[i].y)==2)      
      i++;           
}
fclose(fp);

//OUTPUT OPERATIONS
max_lines = i;
SVG *svg = malloc(array_size * sizeof *svg); // allocate memory
size_t total_length=0, length=0; //total length and length of string
for(i=0; i<max_lines; i++)
{
    sprintf(svg[i].xy , "%d,%d ", coord[i].x, coord[i].y);
    total_length += strlen(svg[i].xy); 
    //printf("%s\n", svg[i].xy);
}

str_joined = (char*)malloc(total_length * sizeof *str_joined); // allocate memory for joined strings
str_joined[0] = '\0'; // empty string we can append to

for(i=0; i<max_lines; i++)
{
         strcat(str_joined, svg[i].xy);
         length = strlen(str_joined);

         str_joined[length+1] = '\0';           /* followed by terminator */

}

FILE *fp_out;
fp_out = fopen(output,"w+"); //erase the content and write on it if exists or create the file and write on it

if(fp_out == NULL)
{
  printf("Error");           
}
else
{
  fprintf(fp_out, "<svg><polyline points='%s'/></svg>" , str_joined);

   printf("Operation successful.\n");
}
//printf("%s\n", str_joined);

}

So any help will be appreciated. Thanks in advance.

//UPDATE

Header:

//definitions
#define MAX_FILE_NAME 100
#define OUTPUT_FILE_NAME "svg_output.svg"

void generate_svg(char *input, char *output);
//storage for coordinates
typedef struct Coord
{
    int x;
    int y;
}Coord;

typedef struct SVG
{
  char xy[20];        

}SVG;

So application crash image :

Destroy
  • 73
  • 1
  • 9
  • 1
    Where does it crash ? Your debugger will tell you. Also please show the calling code as well as variable and type declarations such as `SVG`. – Jabberwocky Aug 12 '15 at 14:27
  • 2
    Note that `getc` returns an `int`. `EOF` may not fit in a `char`. Declare `c` as an `int`. – Kninnug Aug 12 '15 at 14:30
  • 2
    Your `total_length` doesn't include space for a null-terminator. – EOF Aug 12 '15 at 14:30
  • Please [see why not to cast](http://stackoverflow.com/q/605845/2173917) the return value of `malloc()` and family in `C`. – Sourav Ghosh Aug 12 '15 at 14:30
  • Unrelated, but `sizeof(char)` is always 1 per definition. – Jabberwocky Aug 12 '15 at 14:31
  • Sİnce I'm using devc++ it shows nothing :)) I also tried in Visual Studio without precompiler header and set as C compiler, I got the malloc problem which says you cannot be initialized with the type "Coord". I'm updating my post with the header parts. – Destroy Aug 12 '15 at 14:32
  • Try `malloc(total_length * 2)` just for testing purposes. If it doesn't crash anymore, then the problem is probably that you don't allocate enough memory and you write beyont the allocated memory. – Jabberwocky Aug 12 '15 at 14:33
  • Kninnug, I have no problem in that part I know it. For example instead of writing with fprintf, I just type like printf("%s", str_joined); it works correctly ? – Destroy Aug 12 '15 at 14:34
  • @Michael Walz, I tried what you saying but it still crashes :( – Destroy Aug 12 '15 at 14:37
  • Test if `fp` is NULL after `fp = fopen(input, "r");`. – Jabberwocky Aug 12 '15 at 14:37
  • @Michael Walz, it doesnt work either. Also I'm using w+ flag which means create file if not exist or delete all content write on it. So it doesnt really matter to check whether ftp_out is null or not – Destroy Aug 12 '15 at 14:39
  • 2
    **Never** assume `fopen` succeeds. It can fail for a lot of (sometimes unexpected) reasons – Jabberwocky Aug 12 '15 at 14:41
  • So what you are suggesting me. I must do this in C, I'm even better in C++ but This is required like this for the work. – Destroy Aug 12 '15 at 14:43
  • 4
    @Destroy we suggest you 1: check your `fopen` calls for `NULL`s. 2: use [`snprintf`](http://en.cppreference.com/w/c/io/fprintf) instead of `sprintf` to prevent overflow. 3: `malloc` string-length + 1 for your strings, don't cast the result but do check if it isn't `NULL`. – Kninnug Aug 12 '15 at 14:48
  • I check fopen whether it is null or not. I looked at the malloc issue and fixed it i guess. But nothing changed right now. So finally, I'm going to check the "snprintf", After checking I will write the result again. – Destroy Aug 12 '15 at 14:52
  • @Destroy can you tell us **where excatly** the crash occurs and what is the error message you get ? – Jabberwocky Aug 12 '15 at 14:53
  • I'm getting crash when the buffer is writtin in svg file. I know since when I change it to printf to check the buffer is correct. It is correct. But I tested that when the buffer size bigger than 16-18 kb I'm getting this crash. For instance, when I got input as 40 kb, when the writing process, it crashes. I'm not getting any error message because of the stupidity of devexpress. Now, I'm trying to compile with gcc. – Destroy Aug 12 '15 at 15:02
  • @Kninnug, I tested but ı have no problem with sprintf either. It gets any buffer in anysize without any error. So let me see what's going to happen when compiling in gcc. I'll write soon – Destroy Aug 12 '15 at 15:04
  • So, I compiled with GCC but there is no error as not in devexpress. I have getting crash without any warning while program running. Cant get it really :( – Destroy Aug 12 '15 at 15:32

1 Answers1

0

Ok, Thanks for the helps really. I solved the problem. I configured the Visual Studio for C compiling and also standardized my code as C99. So final shape of my code is the following and it works.

void generate_svg(char *input, char *output)
{

    //INPUT OPERATİONS //

    FILE *fp, *fp_out;  SVG *svg;  Coord *coord;
    int array_size = 0, i=0, max_lines = 0;  // Line counters
    char c;  // To store a character read from file to check whether newline or not
    char *str_joined = NULL;
    size_t total_length=0, length=0;

    // Open the file
    fp = fopen(input, "r");
    if (fp == NULL)
    {
        perror("Error");
    }
    else
    {
         //Count the number of lines for the array size 
        for (c = getc(fp); c != EOF; c = getc(fp))
            if (c == '\n') 
                array_size = array_size + 1;
        fclose(fp);
    }




    // read the file into an array of coordinates
    coord = (Coord*)malloc(array_size * sizeof(Coord)); //preallocation for performance
    fp = fopen(input, "r");
    if (fp == NULL)
    {
        perror("Error");
    }
    else
    {
        while(!feof(fp))
        {
           //check whether input getting correctly             
           if(fscanf(fp, "%d, %d", &coord[i].x, &coord[i].y)==2)      
              i++;           

        }
        fclose(fp);
    }


    //OUTPUT OPERATIONS
    max_lines = i;
    svg = (SVG*)malloc(array_size * sizeof(SVG)); // allocate memory
     //total length and length of string
    for(i=0; i<max_lines; i++)
    {
        sprintf(svg[i].xy , "%d,%d ", coord[i].x, coord[i].y);
        total_length += strlen(svg[i].xy); 
        //printf("%s\n", svg[i].xy);
    }

    str_joined = (char*)malloc(total_length * 2); // allocate memory for joined strings
    str_joined[0] = '\0'; // empty string we can append to

    for(i=0; i<max_lines; i++)
    {
        strcat(str_joined, svg[i].xy);

    }

    fp_out = fopen(output,"w+"); //erase the content and write on it if exists or create the file and write on it
    if (fp_out==NULL)
    {
        perror("Error");
    }
    else
    {
        fprintf(fp_out, "<svg><polyline points='%s'/></svg>" , str_joined);
        printf("Operation successful.\n");
    }


    //printf("%s\n", str_joined);




}
Destroy
  • 73
  • 1
  • 9