[C]Tablice dwuwymiarowe i ciągi znaków

0

Mam do napisania zadanie, które z początku wydaje sie banalne, ale niestety nie do końca dla mnie jest.

Treść:
Napisz program wczytujący w klawiatury teksty o różnej długości przechowujący je w pamięci komputera w postaci tekstów. Wykorzystaj reprezentacje w postaci statycznej tablicy 30-sto elementowych tablic znaków.

Do wczytywania użyłam getchara. Jeśli użytkownik poda wiecej niż 30 znaków, to nadmiar idzie do nastepnego ciągu. Co mogę zrobić, żeby tak nie było? fflush niestety do stdtina chyba użyć nie mogę...

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

#define ILOSC 10
#define DLUGOSC 30

int main(void) {
	int i,j,k;
	char tab[ILOSC][DLUGOSC];
	char ch;

	k = 0;
	printf("Podaj %d tekstow o maksymalnej dlugosci %d znakow. Enter konczy "
			"wpisywanie danego ciagu.\n", ILOSC, DLUGOSC);
	for(i = 0; i < ILOSC; i++) {
		printf("Ciag %d: ", i+1);
		while(((ch = getchar()) != '\n') && (j < DLUGOSC +1)) {
			tab[i][j] = ch;
			j++;
		}
		tab[i][j] = '\0';
		j = 0;
	}
	for(i = 0; i < ILOSC; i++) {
		printf("Ciag %d: ", i+1);
		printf("%s\n",tab[i]);
	}
	exit(EXIT_SUCCESS);
}  /* main */


0

Jeśli dobrze rozumiem, to nadmiar znaków zostaje w strumieniu, i jest stamtąd wyciągany podczas wczytywania następnego napisu, przez co zapisuje się w następnym polu.

Musisz wyciągnąć te znaki przed wczytaniem następnego napisu.
Napisz program tak, aby w wypadku zbyt długiego napisu była dodatkowa pętla z getcharem który będzie wyciągał te znaki aż do \n

0

mnie się wydaje że gets załatwi sprawę. skoro tekst ma mieć maksymalną długość 30 znaków (w zasadzie 29 bo ostatni to znak 0) to wszystko powinno dzialac ok

#include <stdio.h>

#define ILOSC 10
#define DLUGOSC 30

int main()
{
  int i;
  char tab[ILOSC][DLUGOSC];

  printf("Podaj %d tekstow o maksymalnej dlugosci %d znakow. Enter konczy "
                  "wpisywanie danego ciagu.\n", ILOSC, DLUGOSC);
  for (i=0; i<ILOSC; i++)
    gets(tab[i]);

  for(i = 0; i < ILOSC; i++)
   {
    printf("Ciag %d: ", i+1);
    printf("%s\n",tab[i]);
   }
  return 0;
}
0

Hmm...

http://www.digipedia.pl/man/doc/view/getc.3/ napisał(a)

gets() odczytuje linię z stdin do bufora wskazywanego przez s aż do kończącego znaku nowej linii lub EOF, który jest zastępowany przez ‘\0’. Nie jest sprawdzane przepełnienie bufora (zobacz BŁĘDY poniżej).

Na pewno o tą funkcję ci chodziło?

Zmodyfikowałem trochę pierwszą pętlę, dodałem jeszcze jedną pętlę i użyłem zmiennej k.
Kodu nie miałem jeszcze okazji przetestować (zrobie to po południu), mam nadzieję że działa.

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

#define ILOSC 10
#define DLUGOSC 30

int main(void) {
	int i,j,k;
	char tab[ILOSC][DLUGOSC];
	char ch;

	k = 0;
	printf("Podaj %d tekstow o maksymalnej dlugosci %d znakow. Enter konczy "
			"wpisywanie danego ciagu.\n", ILOSC, DLUGOSC);
	for(i = 0; i < ILOSC; i++) {
		printf("Ciag %d: ", i+1);
		while((ch = getchar()) != '\n') {
			if(!(j < DLUGOSC +1)){k=1;break;}
			tab[i][j] = ch;
			j++;
		}
		tab[i][j] = '\0';
		j = 0;
		if(k){
			while(getchar() != '\n'){}
			k=0;
		}
	}	
	for(i = 0; i < ILOSC; i++) {
		printf("Ciag %d: ", i+1);
		printf("%s\n",tab[i]);
	}
	exit(EXIT_SUCCESS);
}  /* main */


0

Podaj %d tekstow o maksymalnej dlugosci %d znakow. Enter konczy wpisywanie danego ciagu.

skoro prosimy uzytkownika o krotszy to po co mialby dluzszy wprowadzic?

poza tym zawsze można użyc fgets:
http://www.cplusplus.com/reference/clibrary/cstdio/fgets/

jako plik podajemy stdin i obsluguje on maksymalna liczbe znakow

0

Program ma być odporny na takie błedy. Dla tego musze mieć pewność, że za każdym razem bede miała czysty stdin.

Reads characters from stream and stores them as a C string into str until (num-1) characters have been read or either a newline or a the End-of-File is reached, whichever comes first.

Wydaje mi się,że dalej to co użytkownik wpisze nadmiarowobędzie szło do nastepnego wczytywania...


@olo16 prawie działa ;). Jest coś nie tak z zapisywaniem następnego elemenu elementu ale zaraz to naprawie .
0

krwq - nie rozumiesz, że to, co nie zostanie wczytane (czyli powyżej limitu), zostanie w strumieniu, i zostanie stamtąd wyciągnięte przy najbliższym wczytywaniu? I to obojętnie, czy do wyciągania użyjesz getchar(), gets(), czy fgets()! Trzeba po wczytaniu części zbyt długiego ciągu wyciągnąć ze strumienia wszystko do końca linii i to właśnie robi mój kod (jeśli dobrze działa).

0

Napisane w C++. Aby zmniejszyć ilość wprowadzanych znaków, ograniczyłem wielkość tablicy. Można wprowadzić 3 ciągi znaków po 4 znaki w ciągu.

#include <iostream>
#include <conio.h>
using namespace std;
   int main()
   {
      const int ile_znakow=4;  
      char ch,tab[3][ile_znakow];
      int i=0,j=0;  
       cout<<"podawaj znaki"<<endl;
        while(1)
         {
           ch=getch();cout<<ch;
           tab[i][j]=ch;  
           j++;
           if(j>3){i++;j=0;}
           if(i>2)break;
         } 
      cout<<endl<<endl;     
      for(i=0;i<3;i++)
      for(j=0;j<ile_znakow;j++)
       {
         cout<<tab[i][j];
          if(j==ile_znakow-1)cout<<endl;
        }     
    cout<<"press any key";
   getch();
   return 0;
}         
0

a tak nie prościej:

#include <stdio.h>
#include <conio.h>

#define ilosc_ciagow 3
#define ilosc_znakow 4
#define dlugosc ilosc_ciagow*ilosc_znakow

int main()
{
  printf("Podaj znaki:\n");
  char buff[dlugosc];
  for (int i=0; i<dlugosc; i++)
    buff[i] = getche();
  printf("\n\n");
  for (int i=0; i<ilosc_ciagow; i++)
   {
    for (int j=0; j<ilosc_znakow; j++)
      printf("%c",buff[i*ilosc_znakow+j]);
    printf("\n");
   }
  getch();
  return 0;
}
0

Niestety, ale:

conio.h is a C header file used in old MS-DOS compilers to create text user interfaces. It is not described in The C Programming Language book, and it is not part of the C standard library, ISO C nor is it required by POSIX.

Wykorzystałam pomysł @olo16. Dzięki!

0

conio.h is a C header file used in old MS-DOS compilers to create text user interfaces.

Nieprawda. Współczesne kompilatory również mają conio.h. Tylko nie wszystkie.

0

Czyli odpada. Pisanie nieprzenośnego kodu nie jest dobrym nawykiem.

0
Olivia napisał(a)

Czyli odpada. Pisanie nieprzenośnego kodu nie jest dobrym nawykiem.
Tylko że niestety większość bibliotek od GUI jest nieprzenośna, więc zostaje pisać aplikacje konsolowe albo w javie...

0
Olivia napisał(a)

Czyli odpada. Pisanie nieprzenośnego kodu nie jest dobrym nawykiem.

Ogromna większość komercyjnego kodu jest nieprzenośna. Czy oni wszyscy mają złe nawyki?

//q: dokladnie tak. albo tez maja INNE zalozenia projektowe lubbiznesowe:)

0
Azarien napisał(a)
Olivia napisał(a)

Czyli odpada. Pisanie nieprzenośnego kodu nie jest dobrym nawykiem.

Ogromna większość komercyjnego kodu jest nieprzenośna. Czy oni wszyscy mają złe nawyki?
W zasadzie to tak... :P Tylko już nic się na to nie poradzi, że większość programów jest na windowsa.

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