问题
Hello i'm so new in the programming and want to learn some from you :) I'm doing a program in .c and i am stucked in a part. I want to get 3 or more inputs max size of 5 characters. (For example: HELLO, HI, GOOD, BYE) And i want to stack them in a new string which holds same letters only once from those 4 strings (Example: H,E,L,L,O,I,G,D,B,Y)
#include <stdio.h>
#include <string.h>
int main(void) {
char first[5], second[5], third[5], fourth[5];
printf("Enter 1st word: \n"); scanf(" %5s", &first);
printf("Enter 2nd word: \n"); scanf(" %5s", &second);
printf("Enter 3rd word: \n"); scanf(" %5s", &third);
printf("Enter 4th word: \n"); scanf(" %5s", &fourth);
char stack[21]; // i want a new string like this and then combine first 4 strings
// in this string...
return 0;
}
I hope you can let me know with which way i can do it. (I'm also new in the site. I searched for this but i couldn't find. Sorry if it exists.)
回答1:
First some comments on your code:
- As somebody else has already mentioned in a comment, you need a buffer of size n + 1 to hold an n character string. This is because in C, the length of a string is not stored anywhere. Instead, a special NUL byte is appended to the string that marks its end. Therefore, your
first
, …,fourth
arrays should be of length at least 6. - What if the worst case happens and a user enters four disjoint words each worth 5 characters? Then your combined string will count 20 characters. So your
stack
array should be able to accommodate 21 characters (again 1 for the terminating NUL byte). (Also mentioned by user3121023's comment.) - To read a string using
scanf
, pass an argument of typechar *
, notchar (*)[6]
.first
already decays tochar *
so don't additionally take its address (as in&first
). Turn on your compiler's warnings (use at least-Wall
) to be informed about such bugs. (Also mentioned by Dere0405 while I was typing this answer.) - Your use of
scanf
is insecure. If the user inputs a string longer than 5 characters, you'll read beyond the end of your array. You could modify the format specifier to read%5s
to tellscanf
to stop reading after the 5th character. However, this will leave excess characters at the end of the line. A better option would be to use fgets or getline to read an entire line of input. Alternatively, simply pass the strings as command line arguments (my preferred solution).
Now to the actual problem:
I won't give you a complete solution but only some hints because this looks very much like homework. (Unfortunately, someone else has already given you the full code so you will likely ignore my answer.)
You'll have to loop over all five strings and check for each character if it was already added to the stack
. If so, continue, otherwise, append it to the stack
. To loop over a string, we can use the following idiom.
int i;
for (i = 0; first[i]; ++i)
printf("The character at position %d is '%c'\n", i, first[i]);
Alternatively, if we don't need to refer to the current index, the following idiom is more compact.
char * pos;
for (pos = first; *pos; ++pos)
printf("The current character is '%c'\n", *pos);
Note how we use the fact that first
– being a C string – is terminated with a NUL byte which evaluates to false. Otherwise, we would not know where to stop iterating.
Now that we know how to loop over the characters of a string, how can we check whether a character was already added? Two solutions come into mind:
Loop over
stack
and compare each element to the current character in question. While for your short strings, this might be the method of choice, it will grow inefficient for longer strings.Create a counter for each character and increment it whenever added to
stack
. You can use the fact thatchar
s are just numbers. So you could create an array with 256 elements (there are 256 differentchar
s) all initially set to 0 and then increment the position for the character currently added. For example:int counters[256]; memset(counters, 0, sizeof(counters)); /* fill with 0s */
And then later in your code:
if (counters[(unsigned char) (*pos)]++) { /* Character was already added. Do nothing. */ } else { /* Character was not added yet. Add it to stack. */ }
The
if (counters[(unsigned char) (*pos)]++)
is a little tricky. First,*pos
dreferences the pointerpos
to yield the current character which is then interpreted as anunsigned char
because arrays cannot have negative indices. That position is then looked up in thecounters
array and evaluated in theif
statement. Finally, the value is incremented (but only after comparing) via the post-increment operator.
Don't forget to terminate stack
with a NUL byte at the end.
回答2:
Please update your code as following:
printf("Enter 1st word: \n"); scanf(" %s", &first);
to
printf("Enter 1st word: \n"); scanf(" %s", first);
Please update to other lines.
回答3:
Try:
#include <stdio.h>
#include <string.h>
int main(void) {
char strings[4][6];
printf("Enter 1st word: \n"); scanf(" %s", strings[0]);
printf("Enter 2nd word: \n"); scanf(" %s", strings[1]);
printf("Enter 3rd word: \n"); scanf(" %s", strings[2]);
printf("Enter 4th word: \n"); scanf(" %s", strings[3]);
char stack[21]; // This needs to be pretty much bigger than all combined just in case
// Initialize the stack string to 0 length
stack[0] = '\0'
// Move through each word
for(unsigned char word = 0; word < 4; word++){
// Move through each letter of each word
for(unsigned char letter = 0; letter < strlen(strings[word]); letter++){
// Test to see if the current letter is within the current stack string
unsigned char schar;
for(schar = 0; schar < strlen(stack); schar++){
if(stack[schar] == strings[word][letter]) break;
}
if(schar >= strlen(stack)){
unsigned char sstacklen = strlen(stack);
stack[sstacklen] = strings[word][letter];
stack[sstacklen+1] = '\0';
}
}
}
return 0;
}
This should work for what you are wanting, this was a quick write, so there may be small errors!
来源:https://stackoverflow.com/questions/27334684/combining-two-strings-into-one-string-which-eliminates-the-same-letters-in-c