NO

Author Topic: probably one of the silly errors  (Read 3102 times)

czerny

  • Guest
probably one of the silly errors
« on: November 30, 2014, 03:54:26 PM »
I have a runtime error in this code and can not find it:

Code: [Select]
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.

laurro

  • Guest
Re: probably one of the silly errors
« Reply #1 on: November 30, 2014, 05:39:32 PM »
czerny, it should not be ?

Code: [Select]
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

czerny

  • Guest
Re: probably one of the silly errors
« Reply #2 on: November 30, 2014, 07:06:31 PM »
czerny, it should not be ?
Laur! As I said, silly ^ 5! Thank you!!

laurro

  • Guest
Re: probably one of the silly errors
« Reply #3 on: December 01, 2014, 12:27:04 AM »
If you do not mind losing the old new lines, how about this ?

Code: [Select]
#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;
}


Code: [Select]
[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

czerny

  • Guest
Re: probably one of the silly errors
« Reply #4 on: December 01, 2014, 08:52:52 AM »
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:

Code: [Select]
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);
}

« Last Edit: December 01, 2014, 09:34:43 AM by czerny »