Wyświetlanie łańcucha według długości pierwszego słowa.

0

Witam piszę program, który ma za zadanie pobrać maksymalnie 10 łańcuchów znakowych oraz wykonywać następujące rzeczy po wybraniu odpowiedniej cyfry w menu:

  1. Wyświetlenie pierwotnej listy łańcuchów.
  2. Wyświetlenie łańcuchów w porządku ASCII.
  3. Wyświetlenie łańcuchów według długości (rosnąco).
  4. Wyświetlenie łańcuchów według długości pierwszego słowa.
  5. Koniec.

Mam następujący kod (nie wrzucam wszystkich funkcji tylko tą niedziałającą poprawnie):

#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#define LANCUCHY 10
#define ROZMIAR 101

void menu(void);
void wyczysc(void);
void lista(char *y[], int x);
void ASCII(char *y[], int x);
void dlugosc(char *y[], int x);
void pierwsze(char *y[], int x);

int main(void)
{
	char tab[LANCUCHY][ROZMIAR];
	char *wsk[LANCUCHY];
	int licz = 0, wybor;

	puts("Podaj maksymalnie dziesiec lancuchow znakowych");
	puts("Wcisnji enter aby zakonczyc");
	printf("Podaj %d lancuch\n", licz + 1);
	while ((licz < LANCUCHY) && (gets(tab[licz]) != NULL) && (tab[licz][0] != '\0'))
	{
		wsk[licz] = tab[licz];
		licz++;
		printf("Podaj %d lancuch\n", licz + 1);
	}
	menu();
	while (scanf("%d", &wybor))
	{
		switch(wybor)
		{
		case 1 :
			lista(wsk, licz);
			menu();
			break;
		case 2 :
			ASCII(wsk, licz);
			menu();
			break;
		case 3 :
			dlugosc(wsk, licz);
			menu();
			break;
		case 4 :
			pierwsze(wsk, licz);
			menu();
			break;
		case 5 :
			wyczysc();
			menu();
			break;
		case 6 : 
			return 0;
		default :
			puts("Wybierz liczbe od 1 do 6");
			menu();
		}
	}
	getchar();
	getchar();
	return 0;
}

void pierwsze(char *y[], int x)
{
	int i, j;
	char *tmp;
	char *wsk[10];

	/*for (i = 0; i < x; i++)
	{
		while (*y[i] != ' ')
		{
			wsk[i] = y[i];
		}
	}*/

	for (i = 0; i < x - 1; i++)
	{
		for (j = i + 1; j < x; j++)
		{
			if (strlen(wsk[i]) > strlen((wsk[j])))
			{
				tmp = wsk[i];
				wsk[i] = wsk[j];
				wsk[j] = tmp;
			}
		}
		puts(wsk[i]);
	}
	puts(wsk[x - 1]);
}

Chciałem aby do wsk była kopiowana z y część łańcucha tylko do momentu napotkania pierwszej spacji, a potem tylko porównanie długości tych łańcuchów. Jednak nie wiem bardzo jak to zrealizować i czy istniej w ogóle taka możliwość w tak zbudowanej funkcji. Prosiłbym o jakieś porady w tej kwestii.

0

Ten wykomentowany fragment to powinien być tak:

for (i = 0; i < x && *y[i] != ' '; i++)
        {

                        wsk[i] = y[i];
        }

A potem to już chyba wystarczy tylko porównać x i i?

0
olek1 napisał(a)
char *wsk[10];

Jesteś pewien, że tego chcesz?

0
Kumashiro napisał(a)
olek1 napisał(a)
char *wsk[10];

Jesteś pewien, że tego chcesz?

OK, jednak tego chcesz... :D
Można się pobawić. Np. możesz znaleźć spację przy pomocy strchr() i kopiować tylko do tego miejsca.

0

BTW, nie musisz kopiować żeby sprawdzić długość, gdyż jak będziesz miał wskaźnik z strchr(), to długość możesz sobie obliczyć i nie korzystać z strlen().

0
aurel napisał(a)

Ten wykomentowany fragment to powinien być tak:

for (i = 0; i < x && *y[i] != ' '; i++)
        {

                        wsk[i] = y[i];
        }

A potem to już chyba wystarczy tylko porównać x i i?

Niestety to nie działa.

Kumashiro napisał(a)
olek1 napisał(a)
char *wsk[10];

Jesteś pewien, że tego chcesz?

Chcę tego.;d To jest tylko po to żeby funkcja nie modyfikowała mi kolejności wpisanych na początku łańcuchów, bo potem po wyborze 1, te łańcuchy byłyby niepoprawnie wyświetlane przez program.

Teraz tak się zastanowiłem to to kopiowanie tylko do spacji nie jest zbyt dobrym pomysłem, ponieważ potem wyświetli mi niepełny łańcuch.

1

No to wylicz sobie długość ze wskaźników:

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


int main(int  argc, const char  *argv[]) {
    long        size;


    size = strchr(argv[1], ' ') - argv[1];
    if ( size < 0 ) {
        size = strlen(argv[1]);
    };

    printf("First word length: %li\n", size);
    return 0;
}
0

Dzięki za pomoc. Ja tak napisałem swoją funkcję i wygląda na to, że wszystko działa jak należy:

void pierwsze(char *y[], int x)
{
	int i, j;
	char *tmp;
	char *wsk[10];


	for (i = 0; i < x; i++)
	{
		wsk[i] = y[i];
	}

	for (i = 0; i < x - 1; i++)
	{
		for (j = i + 1; j < x; j++)
		{
			if ((strchr(wsk[i], ' ') - wsk[i]) > (strchr(wsk[j], ' ') - wsk[j]))
			{
				tmp = wsk[i];
				wsk[i] = wsk[j];
				wsk[j] = tmp;
			}
		}
		puts(wsk[i]);
	}
	puts(wsk[x - 1]);
}
0

Źle. Zwróć uwagę na przykład. Nie bierzesz pod uwagę przypadku, gdy dane wejściowe będą się składały z jednego wyrazu i/lub nie będą posiadały spacji.
Jeśli strchr() nie znajdzie poszukiwanego znaku, zwraca NULL, czyli 0 (tutaj trochę igramy z ogniem, gdyż NULL przy jakiejś dziwnej kombinacji platforma-kompilator może być czymś innym niż 0). Wynikiem odejmowania będzie wtedy liczba ujemna. Np. takie porównanie zwróci wtedy False: "Jeden" > "Ala ma kota".

Jak się głębiej zastanowić, to w zadaniu jest "długość pierwszego słowa", zatem oprócz spacji wypadałoby poszukać także innych znaków. Trzeba uwzględnić następujące przypadki:

Potwierdzam! // długość słowa: 11, nie 12
Potwierdzam, to jest przesada. // długość słowa: 11, nie 12
"Aha", odrzekłem. // długość słowa: 3, nie 6

itp. Chyba, że "słowo" rozumiemy jako "ciąg znaków nie zawierający białych spacji", ale i tak trzeba jeszcze dorzucić test na tabulację (no właśnie, trzeba czy można?).

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