0

I’ve got a problem in sorting a char array like “ANF23ie89Z” and get an output like “2389AFNZei” (by ascii code), what I’ve tried


#include <iostream>
#include <stdio.h>

using namespace std;

int main(){
    char arr[20];
    
    for(int i = 0; i < 20; i++){
        scanf(“%s”, &arr[i]);
        getchar();
    }
    
    for(int i = 0; i < 20; i++){
        for(int j = 0; j < 20 - i - 1; j++){
            if(arr[j] > arr[j+1]){
                int tmp = arr[j+1];
                arr[j+1] = arr[j];
                arr[j] = tmp;
            }
        }
    }
 
    for(int i = 0; i < 20; i++){
        printf(“%s”, arr[i]);
    }
    puts(“”);
    return 0;
}

My idea is storing “ANF23ie89Z” to array like arr[0] = ‘A’, arr[1] = ‘N’,… and sort them by bubble sort & ascii, and last print my input.

But I got nothing in output.

(I know I can use algorithm sort. to sort but my main problem is not about sorting, it’s about scanf(%s) & printf(%s) ?)

Please help!

John Bollinger
  • 160,171
  • 8
  • 81
  • 157
  • Do not spam language tags. C and C++ are different languages. Although the code presented is pretty much written to C idiom, use of namespaces and a C++-style header name makes this C++, not C. – John Bollinger Oct 07 '22 at 13:21
  • More or less. The code presented will not compile as either C or C++, on account of the use of "smart" quotes instead of ASCII double-quotes to delimit strings. Use a code or plain-text editor to write your source code, not a program that tries to be helpful by automagically replacing quotes with smart quotes. And when you present code to us, do copy & paste real code that has been accepted by a compiler, unless there is a very good reason, inherent in the code, why you cannot do so. – John Bollinger Oct 07 '22 at 13:26
  • Just be aware that there's [`std::sort`](https://en.cppreference.com/w/cpp/algorithm/sort) for sorting efficiently (by value or by custom comparator). While writing your own altorithm is fine if you are just playing around to learn the ropes you absolutely should use the standard ones later on. – Aconcagua Oct 07 '22 at 13:53
  • About [using namespace std](https://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice)… – Aconcagua Oct 07 '22 at 13:54
  • I would advise you to first learn at least C++ (version 11 or later) and learn about the standard library. Your code is actually more like C then C++. For anything string just use std::string. And to input into a char. Use char c; std::cin >> c; (https://www.learncpp.com/ & https://en.cppreference.com/w/cpp/header). Also printf isn't the safest API to use anymore, if you have a C++20 compiler have a look at std::format – Pepijn Kramer Oct 07 '22 at 14:03
  • Ok, I was typing this question on my mobile device, so it might cause some typing issue. I've also run this code on my compiler, but I didn't get what I expect, and this problem have confussed me a few day. Anyway, thanks for helping ! – Oyasumi Oct 07 '22 at 14:37

5 Answers5

1

I am not quiet sure why you're looping over scanf or over printf.This would work without sorting and now you just need a working sorting algorithm

int main(){
    char arr[20];
    scanf("%s", arr);
    
    printf("%s", arr);
    return 0;
}
  • I thought for loop can help me put the "ANF23ie89Z" in separated way, like arr[1]=A, arr[2]=N, arr[3]F...into the arr[20]. Now I know ! thanks ! – Oyasumi Oct 07 '22 at 14:31
0

You can just use scanf("%s", var-name); to store the string data. `

#include <stdio.h>

int main(){
 char arr[20];
 scanf("%s", arr);

 for(int i = 0; i < 20; i++){
    for(int j = 0; j < 20 - i - 1; j++){
        if(arr[j] > arr[j+1]){
            int tmp = arr[j+1];
            arr[j+1] = arr[j];
            arr[j] = tmp;
        }
    }
 }

 for(int i = 0; i < 20; i++){
    printf("%c", arr[i]);
 }
 return 0;
}
//////////////////////////////////////

`

The input was “ANF23ie89Z” and the output was “2389AFNZei”.

shadoww
  • 1
  • 2
0

The characteristics of your code fit more closely to a C program, so analyzing what you are trying to accomplish, following is a version of your code with the usual usage of "scanf" and "printf".

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

int main(){
    char arr[20];

    printf("Enter an array of characters: ");
    scanf("%s", arr);                           /* Input your text into an array, not character by character */

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

    for(int i = 0; i < strlen(arr); i++){
        printf("%c", arr[i]);               /* Use %c for printing a character */
    }
    printf("\n");

    return 0;
}

First off, it is usual and customary to input text with the "%s" format along with the array name (not an individual character position). Also, so as to not go out of bounds, it is usual to utilize the "strlen" function to ensure that the program does not read past the end of the string being analyzed.

With those bits, following is the output I got from entering your test string.

@Una:~/C_Programs/Console/SortWord/bin/Release$ ./SortWord 
Enter an array of characters: ANF23ie89Z
2389AFNZei

Give that a try to see if it meets the spirit of your project.

NoDakker
  • 3,390
  • 1
  • 10
  • 11
0

printf with %s goes through all the characters of the string (pointer to char) you gave as argument until it finds a null char. Thats because strings in C are ended with a null char to denote where the string ends. You gave it char not char * thats why it doesnt work as you want. To print a single character, use printf with %c instead.

MichalH
  • 1,062
  • 9
  • 20
0

My idea is storing “ANF23ie89Z” to array like arr[0] = ‘A’, arr[1] = ‘N’,… and sort them by bubble sort & ascii, and last print my input.

If you want to read one character at a time, each on a separate line, with scanf, then you should use the %c scanf directive (together with some means of consuming the newlines, which your getchar() call provides), and loop once per character you want to read. Example:

    char arr[20];
    puts("Input 20 characters, one per line:");
    for(int i = 0; i < 20; i++){
        scanf("%c", &arr[i]);
        getchar();
    }

Do note that that is at risk to fall out of register if the user types any trailing characters on a line or any blank lines.

If you want to read all the characters on one line, and are prepared to assume that none are space or tab (or other whitespace) characters, then one scanf() call with a %s directive will accomplish it. Example:

    char arr[21];  // <-- one byte is reserved for a string terminator

    puts("Input 20 characters on one line, with no spaces or tabs:");
    scanf("%20s", arr);           // <-- field width prevents buffer overrun
    int num_chars = strlen(arr);  // <-- sort only this many characters

You have instead used a mishmash of the two. It might serendipitously work about as you expect for the one character per line case, but at minimum, it will overrun the bounds of your array by at least one byte in that case because you do not leave room for a string terminator after the 20th character.


But I got nothing in output.

That would be for a different, but related reason: your arr[i] is one character, not a string. When you tell printf to interpret it as a string via the %s directive, you elicit undefined behavior, which is extremely unlikely to be printing the value as if it were a character. I'm surprised that the program does not fail with your system's flavor of memory-access fault. Or does it? That would have been relevant information to include in the question.

In any case, the situation on output is analogous to the one on input: either print characters, one at a time, with %c, or print a whole string, all at once, with %s (or other, similar variations). In the latter case, you must actually have a string, meaning that the data are terminated by a null character. Examples:

    // one character at a time, each on its own line
    for(int i = 0; i < 20; i++){
        printf("%c\n", arr[i]);
    }

    /* OR */

    // all characters on the same line, assuming arr contains a string
    printf("%s\n", arr);

Note also: if you decide to go the string route, be sure to exclude the terminator from your sort. It needs to stay at the end of the string, else the effect will be a logical truncation of the string -- probably to an empty string.

John Bollinger
  • 160,171
  • 8
  • 81
  • 157
  • OMG ! This reply really helps me a lot ! Btw My system didn't crash or what, maybe just lucky ? LUL Thanks again ! – Oyasumi Oct 07 '22 at 15:00