Ich versuche, eine Funktion zu erstellen, die ein Array von Zeichenfolgen und die Größe empfängt und eine Zeichenfolge zurückgibt, die aus dem Buchstaben des größten ASCII-Werts jedes Wortes besteht. Die Größe der Zeichenfolge muss genau angegeben werden, und ich darf nicht using operator [] (das ist mein Hauptproblem).

So für:

char * strArr [SIZE] = {"Hallo", "und", "gut", "Morgen"};

Die Funktion gibt eine Zeichenfolge mit dem Wort zurück

"onor"

.

Also dachte ich daran, eine Double-for-Schleife zu erstellen. Die erste führt mich an die Position jedes Wortes im Array und die innere hilft mir, jedes Wort durchzugehen.

Derzeit habe ich Probleme, mit meinen Zeigern das richtige Format zu finden, um die Buchstaben meines ersten Wortes tatsächlich durchzugehen.

Ich bin mir bewusst, dass ich nicht überprüft habe, ob meine Speicherzuordnung gültig ist, und auch meinen Speicher noch nicht freigegeben habe, da ich zuerst herausfinden möchte, was falsch ist.

char *bigLetters(char *str[], int size)
{
char *strNew = (char *)malloc((size + 1) * sizeof(char));
char max = 'a';

for (int i = 0; i < size; i++)
{
    for (int j = 0; (*(str + i)+j) != NULL; j++)
    {
        if ((*(str + i) + j) >= max)
        {
            max = (*(str + i) + j);
        }

    }
    *(strNew + i) = max;
}
    *(strNew +(size+1)) = NULL;
return *(strNew);
}    

void main()
{
char *strArr[SIZE] = { "hello", "and", "good", "morning" };
char *res = bigLetters(strArr, SIZE);
printf("The new string is --> %s\n", res);

system("pause");
}    
2
Shames 18 Jän. 2019 im 16:41

5 Antworten

Beste Antwort

Es ist einfacher, die Zeiger zu verwenden, wenn Sie den Zeichenfolgenzeiger von seinem Zeichenzeiger trennen. Außerdem muss max für jede Zeichenfolge zurückgesetzt werden, und Sie haben den endgültigen Zeichenfolgenabschluss außerhalb des zugewiesenen Speichers geschrieben. Sie verwenden auch NULL, wo Sie das Zeichen '\0' verwenden sollten.

Schließlich gab die Funktion das erste Zeichen der neuen Zeichenfolge zurück (die ich später free).

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

#define SIZE 4

char *bigLetters(char *str[], int size)
{
    char *strNew = malloc(size + 1);                    // no cast or sizeof necessary

    for (int i = 0; i < size; i++)
    {
        char ch;
        char max = 'a';                                 // moved inside loop
        char *ptr = *(str + i);                         // use a separate pointer
        for (int j = 0; (ch = *(ptr + j)) != '\0'; j++) // pull out the character
        {
            if (ch > max)                               // >= is not necessary
            {
                max = ch;
            }

        }
        *(strNew + i) = max;
    }
    *(strNew + size) = '\0';                            // correct the bounds error
    return strNew;                                      // just the pointer not its target
}    

int main(void)                                          // correct signature
{
    char *strArr[SIZE] = { "hello", "and", "good", "morning" };
    char *res = bigLetters(strArr, SIZE);
    printf("The new string is --> %s\n", res);
    free(res);                                          // clean up
    system("pause");
}

Programmausgabe

The new string is --> onor
Press any key to continue . . .
1
Weather Vane 18 Jän. 2019 im 14:07

Wenn Sie Ihrer Codierung keine merkwürdigen und nicht hilfreichen Einschränkungen auferlegt haben, können Sie die Probleme mit Ihrem Code schnell erkennen oder sogar vermeiden, sie überhaupt erst zu erstellen. Das Problem ist, dass die folgende Anweisung keinen Sinn ergibt: Sie vergleichen ein char * mit einem char, da Sie str nur einmal de-referenzieren.

if ((*(str + i) + j) >= max)

Dies ist das gleiche wie beim Schreiben

if ((str[i] + j) >= max)

Was Sie den offensichtlichen Fehler sehen können, da das, was Sie zu schreiben versuchen, das Äquivalent von ist

if ((str[i][j]) >= max)

Welches sein würde

if (*(*(str + i) + j) >= max)

Ihr Compiler sollte Warnungen auslösen, da ein Vergleich zwischen einem Zeiger und einer Ganzzahl selten gewünscht wird.

0
Chris Turner 18 Jän. 2019 im 14:07

Sie können Zeiger als Positionsanzeigen verwenden und diese nach Bedarf vorrücken.

#include <stdio.h>
#include <stdlib.h>
#define SIZE 4

char
biggest_ascii(char* str)
{
 char c = 0;
 int i;

 for (i = 0; *str; str++)
    if (*str > c)
        c = *str;
 return c;
}


int
main()
{
 int i;
 char* strArr[SIZE] = {"hello", "and", "good", "morning"};
 char** ppch;// current string
 char res_str[SIZE + 1] = {0};/* resulting string, 
            initilized to 0 to be 0-terminated */
 char* pch;// current char position

 for (i = 0, ppch = strArr, pch = res_str; i < SIZE; i++, ppch++, pch++)
    *pch = biggest_ascii(*ppch);

 printf("%s\n", res_str);   
 return 0;
}
0
purec 18 Jän. 2019 im 14:37

Erstens ist (*(str + i)+j) nicht der gute Weg.

Sie könnten alle ersetzen

(*(str + i) + j)

Durch :

str[i][j]

Dann müssen Sie max auf "a" zurücksetzen, da es 'o' ist, wenn Sie die Schleife verlassen, sodass Ihr Zustand zu str[i][j] >= o wird, was nicht das ist, was Sie wollen. Mach es vor dem zweiten for.

Und ich hätte while anstelle von for für die erste Schleife verwendet.

Ich habe Ihren Code bearbeitet und diese Version funktioniert gut für mich:

#include <stdlib.h>


char *bigLetters(char *str[], int size)
{
    char *strNew = (char *)malloc((size + 1) * sizeof(char));
    int i = 0;

    while (i < size) {
        char max = 'a';
        for (int j = 0; str[i][j]; j++) {
            if (str[i][j] >= max) {
                max = str[i][j];
            }
        }
        strNew[i] = max;
        i++;
    }
    strNew[i] = '\0';
    return strNew;
}    

void main()
{
    char *strArr[5] = { "hello", "and", "good", "morning"};
    char *res = bigLetters(strArr, 4);
    printf("The new string is --> %s\n", res);
    return 0;
}
0
Titouan Le Floch Riche 18 Jän. 2019 im 15:08

str[i] entspricht *(str + i) und str[i][j] entspricht *(*(str + i) + j).
In Ihrem Code verwenden Sie (*(str + i) + j), was falsch ist.

Wenn char *[] an die Funktion übergeben wird, wird sie in char ** zerfallen. In bigLetters() können Sie also char **str als Parameter angeben. Außerdem entspricht es Ihrer Anforderung - ist mit dem Operator [] nicht zulässig.

Anstatt die Dimension SIZE in char *strArr[SIZE] fest zu codieren, können Sie die leere [] angeben und den Compiler die Dimension basierend auf der Größe des Initialisierers zuweisen lassen. In Ihrem Fall beträgt die Größe des Initialisierers 4, da Sie im strArr Initialisierer 4 Zeichenfolgen angegeben haben. Sie können die Größe von strArr folgendermaßen berechnen:

sizeof(strArr)/sizeof(strArr[0]);

Du kannst tun:

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

char *bigLetters(char **str, size_t size) {

        char *strNew = calloc(size + 1, 1); // sizeof(char) is always 1
                                            // calloc will initialize all bytes in the allocated storage to zero.
                                            // You dont need to add the null terminating character at the end of strNew
        if (strNew == NULL)
                exit(EXIT_FAILURE);

        for (size_t i = 0; i < size; i++) {
                for (size_t j = 0; *(*(str + i)+j) != '\0'; j++) {
                        if (*(*(str + i) + j) > *(strNew + i)) {
                                // You can directly fill the allocated memory with biggest ASCII
                                *(strNew + i) = *(*(str + i) + j);
                        }
                }
        }

        return strNew;
}

int main(void) {
        char *strArr[] = { "hello", "and", "good", "morning" };

        char *res = bigLetters(strArr, sizeof(strArr)/sizeof(strArr[0]));

        if (res != NULL) {
                printf("The new string is --> %s\n", res);
                free (res);
        }
        else
                printf("bigLetters returned NULL\n");

        return 0;
}

Beachten Sie, dass der Rückgabetyp void main() nicht dem Standard entspricht. Stattdessen sollten Sie int als Rückgabetyp von main() verwenden.

0
H.S. 18 Jän. 2019 im 19:02