Program wyświetlający słowa w innych liniach

0

Witam, nazywam się Tomek. Zaczynam studia Informatyczne od września. Jestem prawie laikiem w dziedzinie programowania. Więc zacząłem się uczyć.
Mój program ma na celu odczytać wpisany tekst po czym każde jego słowo wypisać w osobnej linijce.

 
#include <stdio.h>

main()
{
      int c;
      c = getchar();
          while(c != EOF){
                   putchar(c);
                   c = getchar();
                   if(c == ' '|| c == '\t' || c == '\n')
                   printf("\n");
                   putchar(c);
                   c = getchar();
                   }
          
                
      
system("PAUSE");
      return 0;

}

Jednak przy dłuższych tekstach zdarza się, że program w jednej linii wyświetli 2 - 3 słowa.

0

"dlaczego zło? ;) jeszcze się nie zawiodłem :) - kolaszek"
dlatego, ponieważ aby twój program działał poprawnie potrzebujesz innego zewnętrznego programu "pause", który poza tym nie musi być obecny na innych systemach operacyjnych. Po co tracić na przenośności z powodu głupiego (i niepotrzebnego w zasadzie) zatrzymania programu na końcu jego działania. Skoro jednak chcesz już zatrzymywać to lepiej zainteresować się bardziej standardowymi (i przenośnymi) sposobami uczynienia tego samego :]

0

bo testowanie robisz tylko dla co drugiego znaku, za dużo masz tego c = getchar(); putchar(c); wewnątrz pętli.

0

Okej, zainteresuje się tym ;)
A teraz do rzeczy. Co sądzicie na temat mojego problemu?

Edit. Dzięki Marek, zaraz przejrzę rozwiązanie :)

0

Czy dobrze myślę?

podczas kiedy c nie jest koncem pliku to:
jeśli c równe jest spacji tabulacji lub końcowi linii to wykona instrukcje printf + putchar + c=getchar.
a jesli nie to zacznie od putchar.

Ale skąd komputer wie ze ma zacząć od putchar?

Edit: Już zrozumialem ;)

0

Ja bym to zrobił tak, chyba prościej?:
1.fgets pobieram całą linię tekstu
2. w pętli wypisuje po literce tekstu, jeśli natrafię na spacje/tabulator, wypisuję znak nowej linii

@Edit
To masz kod:


#include <stdio.h>
#include <string.h>
#define MAX 1000000

char linia[MAX];

int main()
{
    fgets(linia, MAX, stdin);
    int i = 0;
    while(i < strlen(linia))
    {
        if(linia[i] == ' ' || linia[i] == '\t')
            printf("\n");
        else
            printf("%c", linia[i]);
        i++;
    }
    return 0;
}
0

Uczę się z książki Język ANSI C i używam tylko tych funkcji które znam :)

0
kolaszek napisał(a)

Mój program ma na celu odczytać wpisany tekst po czym każde jego słowo wypisać w osobnej linijce.

ja bym to zrobił [w C++] tak:

#include <iostream>
#include <string>

int main(int argc, char **argv)
{
	std::string linijka ;
	std::cout<<"Podaj linijke: ";
	getline(std::cin, linijka) ;
	std::cout<<"\nTwoja podzielona linijka:\n" ;
	
	bool bylaSpacja=1 ;
	for(int i=0; i<linijka.size(); ++i)
	{
		switch(linijka[i])
		{
			case ' ':
			case '\t':
			case '\n':
			{
				if(!bylaSpacja)
				{
					std::cout<<'\n';
					bylaSpacja=1 ;
				}
			}
			break ;
			default:
			{
				std::cout<<linijka[i] ;
				bylaSpacja=0;
			}
		}
	}
	std::cout<<"\n" ;
	
	return 0 ;
}

mój program ma zabezpieczenie przed podwójnymi spacjami obok siebie itp.

0

Tak przyszłościowo pisząc na wypadek gdybyś używał Dev C++:
Dev to zło. Zainstaluj Code::Blocks.

0

ludzie przecież to jest poste jak konstrukcja cepa (mogłem pomylić string formatu, bo nie używałem tego wieki):

char buf[256];
while (scanf("%255s", buf)==1) {
    printf("%s\n", buf);
}
0

Hmmm... Jednej rzeczy nie rozumiem. Wątkotwórca pisze program pod Windows. Zatem czy nie powinniśmy przypadkiem obsługiwać na wejściu także znaku powrotu karetki? Na konsoli go nie widać, ale IMHO nawet w trakcie nauki programowania warto się uczulać na takie "drobnostki". Chyba, że Windows z 0C0A przeszedł na 0A (nie jestem na bieżąco).

0

Nie, nie trzeba się tym absolutnie przejmować. Wysłanie \n na konsolę powoduje przejście do nowej linii. Podobnie na wejściu widzimy tylko \n.
Zapis \n do pliku otwartego w trybie tekstowym powoduje zapisanie 0D 0A, zaś przy odczycie znaki 0D są zjadane i widać tylko 0A.
Tak że mimo że wewnętrzna reprezentacja to CR LF, nie musimy o tym wiedzieć, bo z punktu widzenia C jest to po prostu \n.

0

Rozumiem, że CR jest zjadany zanim getchar() się dobierze do strumienia. To nawet dość eleganckie rozwiązanie.
A co w przypadku, gdy znaki CR w strumieniu wejściowym są znaczące? Np. jeśli na stdin lecą dane binarne z rury? Deskryptor jest już otwarty, więc nie mamy wpływu na to, w jakim trybie będzie działał odczyt. Czy też może read() i/lub fread() nie olewają CR?

BTW, ciekawe kto tu bardziej namieszał: CP/M czy Uniksy... a może drukarki z automagicznym CR....

0
piternet napisał(a)

ale to ma być w C, to po cholere wklejasz kod w c++, kolega i tak sobie nie przerobi.

#include <stdio.h>
#include <string.h>

#define STRING_MAX_SIZE 256

int main(int argc, char **argv)
{
	char stringBuffer[STRING_MAX_SIZE] ;
	int space ;
	int stringLength ;
	int i;
	
	printf("Wklep linijke: ") ;
	fgets(stringBuffer, STRING_MAX_SIZE, stdin) ;
	stringLength = strlen(stringBuffer) ;
	
	printf("\nTwoja linijka podzielona na slowa:\n") ;
	
	space=1;
	for(i=0; i<stringLength; ++i)
	{
		switch(stringBuffer[i])
		{
			case ' ':
			case '\t':
			case '\n':
			{
				if(!space)
				{
					printf("%c",'\n');
					space=1 ;
				}
			}
			break ;
			default:
			{
				printf("%c",stringBuffer[i]) ;
				space=0;
			}
		}
	}
	
	
	return 0 ;
}

0
Kumashiro napisał(a)

więc nie mamy wpływu na to, w jakim trybie będzie działał odczyt

mamy:

setmode(fileno(stdin), O_BINARY);
0

I pogubiłem się w tych Waszych postach :). Tymczasem próbowałem napisac kolejny program. Program na celu zmianę znaku tabulacji na spację. Oto on:

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

int main(void){

    int c;
        c = getchar();

    while (c != EOF) {
        if (c = '\t') {
            c = ' ';
            putchar(c);
            c = getchar();
        }
        else {
            putchar(c);
            c = getchar();
        }
    }
    
    return EXIT_SUCCESS;
}

Jednak nie działa poprawnie. Może ktoś rzucić okiem?

0

Bo sam sobie strasznie komplikujesz:

int main()
  {
   int c;
   while((c=getchar())!=EOF) putchar(c=='\t'?' ':c);
   return 0;
  }
0

putchar(c=='\t'?' ':c); - możesz mi to opisać dokładnie?

1

putchar(c=='\t'?' ':c); - możesz mi to opisać dokładnie?

if (c=='\t')
    putchar(' ');
else
    putchar(c);
0

Ok dzięki, myślę, że kiedyś będę pisał na tyle krótko, tymczasem na pewno zostanę przy dłuższym i dla początkujących czytelniejszym zapisie.

0

Mam kolejny problem, a w zasadzie kilka.
Pierwszy to program, program ma za zadanie zliczać cyfry, białe znaki i inne, a potem to wyświetlić. Kod napisałem sam, nie działał więc zajrzałem do książki ale ten z książki też nie działa ;/;/. Może źle przepisałem, już sam nie wiem. Sprawdzam go któryś raz z kolei:

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

int main(void){
    int c, i, nwhite, nother;
    int ndigit[10];
    nwhite = nother = 0;
    c = getchar();
    
    for( i = 0; i < 10; ++i)
         ndigit[i] = 0;
    
    while(c != EOF){
             if(c >= '0' && c <= '9') 
                  ++ndigit[c-'0'];
             else if(c == ' ' || c == '\t' || c == '\n')
                  ++nwhite;
             else
                 ++nother;
                 }
                 
    printf("cyfry = ");
    for (i = 0; i <10; ++i)
        printf(" %d ", ndigit[i]);
    printf("biale znaki = %d, inne znaki = %d\n", nwhite, nother);
    
    return EXIT_SUCCESS;
    
}
 

Nie bardzo rozumiem też tablice ;/;/
W jaki sposób je zapełniamy, w jaki sposób je "odczytujemy" i w ogóle po co one są. Jeśli będzie ktoś tak miły i łopatologicznie mi wytłumaczy :).

W książce mam też zadanie:
Napisz program tworzący histogram długości słów wejściowych.
histogram - czyli graficzne przedstawienie czegoś. Jak ja mam to zrobić? Może jakaś podpowiedź?

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