I have a runtime error in this code and can not find it:
char* xstrcpy(char **d, char *s)
{
char* t = malloc(sizeof(s)+1);
if (t) {
if (*d) free(*d); // here
strcpy(t, s);
*d = t;
}
return *d;
}
I have appended the whole mini project. I want to reformat simple ascii text to a certain line length.
I wanted to create a quick solution. But now I am searching for hours this silly error.
czerny, it should not be ?
char* xstrcpy(char **d, char *s)
{
char* t = malloc(strlen(s)+1);
if (t) {
if (*d) free(*d);
strcpy(t, s);
*d = t;
}
return *d;
}
char* xstrcat(char **d, char *s)
{
char* t = realloc(*d, strlen(*d)+strlen(s)+1);
if (t) {
*d = t;
strcat(*d, s);
}
return *d;
}
Laur
Quote from: laurro on November 30, 2014, 05:39:32 PM
czerny, it should not be ?
Laur! As I said, silly ^ 5! Thank you!!
If you do not mind losing the old new lines, how about this ?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define L 30
int main(int argc, char **argv)
{
FILE *f = fopen("tst.txt", "r");
fseek(f, 0, SEEK_END);
int size = ftell(f);
fseek(f, 0, SEEK_SET);
char *str = malloc(size + 1), *s;
memset(str, 0, size + 1);
s = str;
//fread (str,size,1,f);//
//fseek(f, 0, SEEK_SET);
//printf("%s\n\n", str);
//memset(str, 0, size + 1);
int ch;
ch = fgetc(f);
while (ch != EOF)
{
if (ch != '\n') //we eat newlines they are trouble makers
{
*s = (unsigned char)ch;
if (*s == '\t') //same here, with tabs
*s = ' ';
s++;
}
ch = fgetc(f);
}
fclose(f);
char *p0 = str, *p1 = str, *p, *_isspace = NULL, c, pause[L];
size_t after, before = 0;
while (*p0)
{
c = *p0;
if (isspace(c))
{
after = (unsigned char *)p0 - (unsigned char *)p1;
if (after > L)
{
if ((after - L) <= (L - before))
{
p = malloc(after + 1);
memset(p, 0, after + 1);
memcpy(p, p1, after);
{ // this is only for beauty, at this moment p is a valid char*, you can comment
{ //the brackets, and, btw, the code is unsafe
memset(pause, 0, L);
for (unsigned i = 0; i < (L + L / 2) - strlen(p); i++)
pause[i] = ' ';
}
printf("[%d]_%s %s %.2d %.2d after\n", strlen(p), p, pause, (L - before), (after - L));
}
//printf("%s\n", p);
p0++;
p1 = p0;
free(p);
continue;
}
else
{
p = malloc(before + 1);
memset(p, 0, before + 1);
memcpy(p, p1, before);
{//same here
{
memset(pause, 0, L);
for (unsigned i = 0; i < (L + L / 2) - strlen(p); i++)
pause[i] = ' ';
}
printf("[%d]_%s %s %.2d %.2d before\n", strlen(p), p, pause, (L - before), (after - L));
}
//printf("%s\n", p);
p0 = _isspace;
p0++;
p1 = p0;
free(p);
continue;
}
}
else
{
before = after;
_isspace = p0;
}
}
p0++;
}
//in the last iteration, p0 is '\0' so the last p1 is not displayed
printf("[%d]_%s \n\n\n", strlen(p1), p1);
//printf("%s\n\n\n", p1);
free(str);
return 0;
}
[32]_In RGB mode, pixels can be drawn 04 02 after
[32]_using a function that blends the 02 02 after
[29]_incoming (source) RGBA values 01 04 before
[29]_with the RGBA values that are 01 07 before
[31]_already in the framebuffer (the 04 01 after
[32]_destination values). By default, 07 02 after
[34]_blending is disabled. Use glEnable 05 04 after
[31]_and glDisable with the GL_BLEND 08 01 after
[30]_argument to enable and disable 00 14 before
[34]_blending.When enabled, glBlendFunc 08 04 after
[34]_defines the operation of blending. 06 04 after
[31]_The sfactor parameter specifies 09 01 after
[29]_which of nine methods is used 01 02 before
[25]_to scale the source color 05 07 before
[33]_components. The dfactor parameter 07 03 after
[32]_specifies which of eight methods 06 02 after
[32]_is used to scale the destination 10 02 after
[28]_color components. The eleven 02 07 before
[30]_possible methods are described 00 03 before
[28]_in the following table. Each 02 05 before
[34]_method defines four scale factors, 05 04 after
[30]_one each for red, green, blue, 00 04 before
[29]_and alpha.In RGB mode, pixels 01 03 before
[29]_can be drawn using a function 01 04 before
[33]_that blends the incoming (source) 06 03 after
[32]_RGBA values with the RGBA values 05 02 after
[35]_that are already in the framebuffer 07 05 after
[28]_(the destination values). By 02 07 before
[30]_default, blending is disabled. 00 04 before
[31]_Use glEnable and glDisable with 04 01 after
[31]_the GL_BLEND argument to enable 06 01 after
[21]_and disable blending?
Laur
Thank you, Laur!
There are for sure many solutions for this problem. You treat L as average line length, for me it is a minimum. You treat an empty line as whitespace to skip, for me it is an end-of-paragraph marker and should be maintained as a empty line (the resulting text will be typesetted by ConTeXt, a TeX-package).
Your approach is better, if the line length variation should be as small as possible. But your algorithm has problems if L is small (L < 12).
Here is a solution as a modification of my code:
int nearest(char* s, int i)
{
int j, k;
if (s[i] == ' ') return i;
j = k = i;
do {
if (j) j--;
k++;
} while (s[j] != ' ' && s[k] != ' ');
if (s[j] == ' ') return j;
return k;
}
void out(char* o)
{
char* s = o;
int i = L;
int len = strlen(s);
while (i<len) {
i = nearest(s, i);
s[i] = '\0';
puts(s);
s = &s[i+1];
i = L;
len = strlen(s);
}
if (len) puts(s);
}