funkcja pobierająca dokładnie n znaków

0

Witam,
Próbuje zrobić zadanie, w którym mam do napisania funkcję pobierającą z klawiatury najbliższe n znaków, włącznie z odstępami, tabulatorami i znakami nowej linii.
Problem polega na tym, że nie wiem jak zrobić, aby program po wpisaniu maksymalnej ilości znaków zaprzestał ich pobierania bez przechodzenia do nowej linii (jeśli wklepana została maksymalna ilość znaków).

Czy powinienem użyć w takim wypadku gets() / fgets() operując na łańcuchach?

Poniżej moja funkcja.

#include <stdio.h>
#include <ctype.h>
#define MAX 10
int main()
{
	char ch;
	int n;
	
	while (n != MAX + 1){
		if (ch = getchar() || isspace(ch))
			n++;
	}
	return 0;

} 
2

Skąd to isspace? Nie ma nic o tym w warunkach zadania.

Po prostu n razy wykonaj getchar

0

Chyba nie bardzo rozumiem jak powtórzyć getchar n razy.
Czy mam użyć np. pętli for, czy do while? Niezależnie czego używałem, zawsze musiałem zaakceptować wprowadzony wiersz enterem, przy czym mogło to być 10 znaków ale również 20.

Nie chcę, aby funkcja pozwalała na wklepywanie znaków po załóżmy dziesiątej spacji/literze/enterze itp. (dlatego też dodałem isspace(ch), bo chodzi również o znaki niedrukowane)

0
crystalsky napisał(a):

Chyba nie bardzo rozumiem jak powtórzyć getchar n razy.
Czy mam użyć np. pętli for, czy do while? Niezależnie czego używałem, zawsze musiałem zaakceptować wprowadzony wiersz enterem, przy czym mogło to być 10 znaków ale również 20.

Nie chcę, aby funkcja pozwalała na wklepywanie znaków po załóżmy dziesiątej spacji/literze/enterze itp. (dlatego też dodałem isspace(ch), bo chodzi również o znaki niedrukowane)

To chyba będzie ci potrzebna biblioteka ncurses.h jak chcesz się bawić w zaawansowane sterowanie terminalem

1

if (ch = getchar() || isspace(ch)) ten warunek nie ma zbyt wiele sensu. getchar odczytuje ze standardowego wejścia jeden znak (również białe znak) i zwraca go w postaci unsigned char. (ch = getchar()) zwróci kod ascii, więc będzie prawdą ZAWSZE, bo nie da się (w normalny sposób bez kombinowania z remapem) z klawiatury wprowadzić '\0' aby warunek też zwrócił 0. Teraz isspace(ch) zwróci 1 gdy ch == 0x20, a nie ma takiej potrzeby bo już getchar zwróci w tym przypadku 1.

Tak naprawdę funkcja isspace zostanie wykonana tylko w przypadku, gdy ch == '\0' (inaczej getchar zwraca prawdę i program od razu skacze do bloku if bez sprawdzania drugiego warunku), a gdy ch == '\0' to nie ma już sensu sprawdzać isspace bo wiemy ze 100% pewnością, że zwróci on 0.

Wniosek, isspace można wypieprzyć bo kompletnie, ale to kompletnie nic sensownego nie robi.

2

stawiam na to, że autor chce bezpośredniego dostępu do klawiatury, a tymczasem nie zdaje sobie sprawy, że tak naprawdę korzysta ze standardowego wejścia skojarzonego z plikiem emulowanym przez klawiaturę.
Ergo dopóki user nie naciśnie enter nie będzie miał interakcji z programem, bo po prostu taka jest natura konsoli (pliku klawiatury).

Prawie na pewno musi wykroczyć poza standardowe biblioteki, by osiągnąć zamierzony cel.
Pod Windows może skorzystać z conio.h, albo lepiej z ncurses, które dostępne jest na wszystkie platformy, ale jest z nim nieco więcej rzeczy do zrobienia.

0

@MarekR22 Problem nie leży tak naprawdę po stronie funkcji getchar a po stronie terminala. getchar bierze jeden znak ze strumienia, a w konsoli strumień jest domyślnie buforowany i flushowany dopiero po znaku nowej linii. Aby mieć natychmiastową reakcję przy getchar, w Linuksie trzeba przestawić terminal aby nie buforował znaków. Można to zrobić za na przykład tak system("/bin/stty raw"); Nie wiem jak to można zrobić na Windowsie.

#errata, trochę się zamotałem, nigdzie nie napisałeś, ze problem jest po stronie getchar, a że taka jest natura termina. Ale to wciąż można zmienić prosto bez ncurses.

0

Dziękuję wszystkim za odpowiedzi.
Może po prostu ja źle rozumiem zadanie, bo wątpię, aby ta funkcja miała być aż tak skomplikowana, bo mimo wszystko są to wciąż początki.
W drugim wariancie tego zadania funkcja ma kończyć działanie właśnie po wprowadzeniu n znaków, spacji, tabulatora lub znaku nowej linii, ale wciąż jestem zależny od przesłania wprowadzonego wiersza enterem, więc i tak automatycznie funkcja by kończyła swoją pracę, ponieważ enter został użyty (a co ze spacją i tabulatorem?).

#include <stdio.h>
#define MAX 10
int main()

{
	char ch;
	int n;
	
	for (n = 0; n < MAX + 1; n++){
		ch = getchar();
		if (ch == '\t' || ch == ' ' || ch == '\0')
			break;
	}
	return 0;
		
} 
1

Upewnij się czy na pewno musisz robić to, o czym piszesz. Jeśli to zadanie podczas początkowej nauki podstaw, zapewne rozwiązanie, które "wczyta" dowolną ilość znaków, a zapisze tylko n może być wystarczające, a Ty za bardzo kombinujesz :)

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