Program łamiący długie wiersze

Odpowiedz Nowy wątek
2014-12-21 12:18
derek999
0

Znalazłem taki program. Jest on dla mnie jasny, oprócz fragmentu w funkcji main dla ostatniego else if. Mianowicie, co się dzieje gdy wpiszę np 30 znaków? Dlaczego program wypisuje ten "połamany" wiersz dopiero po naciśnięciu klawisza enter? Skoro tablica line mieści maksymalnie 10 znaków to gdzie zapisuje się reszta?

#include<stdio.h>
 
#define maxcol  10
const int tabinc = 8;
 
char line[maxcol];
 
int zamtab(int pos);
int znsp(int pos);
int nowapoz(int pos);
void wypisz(int pos);
 
int main() {
  int c, pos;
  pos = 0;
 
  while((c = getchar()) != EOF) {
    line[pos] = c;
    if(c == '\t')
      pos = zamtab(pos);
    else if(c == '\n') {
      wypisz(pos);
      pos = 0;
    } else if(++pos > maxcol) {
      pos = znsp(pos);
      wypisz(pos);
      pos = nowapoz(pos);
    }
  }
  return 0;
}
 
void wypisz(int pos) {
  int i;
  for(i = 0; i < pos; i++)
    putchar(line[i]);
  if(pos > 0)
    putchar('\n');
}
 
int zamtab(int pos) {
  line[pos] = ' ';
  for(pos++; pos < maxcol && pos % tabinc != 0; pos++)
    line[pos] = ' ';
  if(pos < maxcol)
    return pos;
  else {
    wypisz(pos);
    return 0;
  }
}
 
int znsp(int pos) {
  while(pos > 0 && line[pos] != ' ')
    pos--;
  if(pos == 0)
    return maxcol;
  else
    return pos + 1;
}
 
int nowapoz(int pos) {
  int i,j;
 
  if(pos <= 0 || pos >= maxcol)
    return 0;
  else {
    i = 0;
    for(j = pos; j < maxcol; j++) {
      line[i] = line[j];
      i++;
    }
    return i;
  }
} 

Pozostało 580 znaków

2014-12-21 14:44
0

Ja tu widzę off-by-one:

} else if(++pos > maxcol) {

Jeśli pos == maxcol - 1, pos zostaje zwiększone o 1 tj. do wartości maxcol, i ten warunek jest fałszywy. Następuje kolejny obrót pętli, na początku której mamy line[pos] (tożsame z line[maxcol]), czyli Undefined Behaviour. Ktoś zapomniał, że ostatni prawidłowy indeks w tablicy to rozmiar_tablicy - 1.

Pozostało 580 znaków

2014-12-21 16:20
derek999
0

No dobra, może powinno być:

} else if(++pos >= maxcol) { 

Przepisywałem z książki. Chodzi mi o to, że nie rozumiem czemu jak napiszę np: "aaaaaaaaaabbbbbbbbbcccccccccc" i wcisnę enter to dopiero wyświetla się:
aaaaaaaaaa
bbbbbbbbbb
cccccccccc
Tzn, ja wiem, że to jest prawidłowe i tak powinno działać, ale skoro tablica line mieści 10 znaków, to gdzie pozostałe 20 są przechowywane?

Pozostało 580 znaków

2014-12-21 16:39
0

Może to ci pomoże http://code2flow.com

Pozostało 580 znaków

2014-12-21 16:39
0

W buforach konsoli.


Wykonuję programy na zamówienie, pisać na Priv.
Asm/C/C++/Pascal/Delphi/Java/C#/PHP/JS oraz inne języki.

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0