The question is to alphabetically sort the given string inputs in ascending order. I wrote the following code for the same. But after printing the entered names the program instead of sorting the strings is giving segmentation fault. I have spent good time over the issue but couldn't figure out anything. Any help would be appreciated.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
int x,i,j,length;
printf("Enter the number of names you want to sort.\n");
scanf("%d",&x);
char *names[x],*p,name[50],*t;
printf("Enter the names:\n");
for(i=0;i<x;i++)
{
scanf(" %[^\n]",name);
length = strlen(name);
p = (char *)malloc(length+1);
strcpy(p,name);
names[i] = p;
}
printf("Entered names are:\n\n");
for(i=0;i<x;i++)
{
printf("%s\n",names[i]);
}
printf("\n\nThe sorted names are:\n");
for(i=0;i<x-1;i++)
{
for(j=i+1;j<x;j++)
{
if(strcmp(names[i],names[j])>0)
{
strcpy(t,names[i]);
strcpy(names[i],names[j]);
strcpy(names[j],t);
}
}
}
for(i=0;i<x;i++)
{
printf("%s\n",names[i]);
}
return 0;
}
You didn't allocate t so the strcpy(t,names[i]) will segfault.
You can also use strdup()1 to duplicate your strings (instead of malloc() and strcpy()).
And, as your array is of char* elements, you can just swap them directly:
t=names[i];
names[i]=names[j];
names[j]=t;
Regarding your question about pointers, you can consider pointers as uint32_t: they are ”just" values you can assign, like regular integers. It's just their value that is interpreted as an address, rather than a random integer (i.e. its value has a special meaning for the computer, as it is strongly linked to memory).
1: As noted by #WhozCraig, strdup() is not part of the standard library so you'll have to #include the appropriate headers for your platform (it is really widely spread though and hardly a problem).
Related
So I suck with functions and need to debug this. Im pretty sure the function ToPigLating does its job well at converting. However I just need help calling the function ToPigLatin inside of my main function. But when I try doing that I just get a bunch of error codes.
#include <stdlib.h>
#include <string.h>
#define LEN 32
char* ToPigLatin(char* word[LEN]){
char word[LEN];
char translation [LEN];
char temp [LEN];
int i, j;
while ((scanf ("%s", word)) != '\0') {
strcpy (translation, word);
//just pretend I have all the work to convert it in here.
} // while
}
int main(){
printf("Enter 5 words: ");
scanf("%s", word);
ToPigLatin();
}```
Roughly, variables only exist within the function they're declared in. The word in ToPigLatin exists only within ToPigLatin. It is not available in main. This lets us write functions without worrying about all the rest of the code.
You need to declare a different variable in main, it can also be called word, to store the input and then pass that into ToPigLatin.
Let's illustrate with something simpler, a function which doubles its input.
int times_two(int number) {
return number * 2;
}
We need to give times_two a number.
int main() {
// This is different from "number" in times_two.
int number = 42;
// We have to pass its value into time_two.
int doubled = times_two(number);
printf("%d doubled is %d\n", number, doubled);
}
Your case is a bit more complicated because you're working with input and memory allocation and arrays. I'd suggest just focusing on arrays and function calls for now. No scanf. No strcpy.
For example, here's a function to print an array of words.
#include <stdio.h>
// Arrays in C don't store their size, the size must be given.
void printWords(const char *words[], size_t num_words) {
for( int i = 0; i < num_words; i++ ) {
printf("word[%d] is %s.\n", i, words[i]);
}
}
int main(){
// This "words" variable is distinct from the one in printWords.
const char *words[] = {"up", "down", "left", "right"};
// It must be passed into printWords along with its size.
printWords(words, 4);
}
ToPigLatingToPigLating function expects to have a parameter like ToPigLating("MyParameter");
Hello there icecolddash.
First things first, there are some concepts missing. In main section:
scanf("%s", word);
You're probably trying to read a string format and store in word variable.
In this case, you should have it on your declaration scope. After some adjustment, it will look like this:
int main(){
char word[LEN];
As you defined LEN with 32 bytes maximum, your program will not be allowed to read bigger strings.
You're also using standard input and output funcitions as printf, and so you should ever include stdio.h, thats the header which cointains those prototypes already declared, avoiding 'implicit declaration' compiling warnings.
Next issue is how you're declaring your translation function, so we have to think about it:
char* ToPigLatin(char* word[LEN])
In this case, what you wrote:
ToPigLatin is a funcion that returns a char pointer, which means you want your function to probably return a string. If it makes sense to you, no problem at all. Although we got some real problem with the parameter char* word[LEN].
Declaring your variable like this, assume that you're passing an array of strings as a parameter. If I got it right, you want to read all five words in main section and translate each one of them.
In this case I suggest some changes in main function, for example :
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define LEN 32
#define MAX_WORDS 5
char *globalname = "translated";
char* ToPigLatin(char* word){
char *translation = NULL;
//Translation work here.
if ( !strcmp(word, "icecolddash") ){
return NULL;
}
translation = globalname;
return translation;
}
int main(){
char word[LEN];
char *translatedword;
int i;
printf("Enter 5 words: \n");
for ( i=0; i < MAX_WORDS; i++ ){
fgets(word, sizeof(word), stdin);
strtok(word, "\n"); // Just in case you're using a keyboard as input.
translatedword = ToPigLatin(word);
if ( translatedword != NULL ){
//Do something with your translation
//I'll just print it out as an example
printf("%s\n", translatedword);
continue;
}
// Generic couldn't translate message
printf("Sorry, I know nothing about %s\n", word);
}
return 0;
}
The above code translate every word in a fixed word "translated".
In case of reading the exact input "icecolddash", the program will output a generic error message, simulating some problem on translation process.
I hope this help you out with your studies.
There are a few things that I see.
#include <stdio.h>
#include <stdlib.h>
char* ToPigLatin(char* word){
printf(word);
return word;
}
int main(){
printf("Enter 5 words: ");
// declare the variable read into by scanf
char * word = NULL;
scanf("%s", word);
//Pass the variable into the function
ToPigLatin(word);
// Make sure you return an int from main()
return 0;
}
I left some comments in the code with some specific details.
However, the main thing that I would like to call out is the style of the way you're writing your code. Always try to write small, testable chunks and build your way up slowly. Try to get your code to compile. ALWAYS. If you can't run your code, you can't test it to figure out what you need to do.
As for the char ** comment you left on lewis's post, here is some reading you may find useful in building up your intuition:
https://www.tutorialspoint.com/what-does-dereferencing-a-pointer-mean-in-c-cplusplus
Happy coding!
I am trying to copy same characters from an single dimensional char array to each row of a 2d array,but I cant any output.
Expected output:
abcd
abcd
abcd
abcd
Output I got:
process returned -1073741819(0xC0000005) execution time : 4.583s
press any key to continue
Here's the code:
#include <stdio.h>
#include <conio.h>
#include <string.h>
void main()
{
int i,j;
char v[4]={'a','b','c','d'};
char answers[10][10];
for(i=0;i<4;i++){
for(j=0;j<4;j++){
strcpy(answers[i][j],v[i]);
}
}
for(i=0;i<4;i++){
printf("\n%s",answers[i]);
}
getch();
}
Strings in C are null-terminated. Try this instead:
char v[5] = { 'a','b','c','d', '\0' };
Also this here
for(i=0;i<4;i++){
for(j=0;j<4;j++){
strcpy(answers[i][j],v[i]);
}
}
Doesn't work because you're trying to copy characters, but this function expects strings. Your compiler should issue a warning about incompatible types. Replace this nested loop with this:
for (i = 0; i < 4; i++) {
strcpy(answers[i], v);
}
You are using
strcpy(answers[i][j],v[i]);
but, neither answers[i][j] nor v[i] is a string (or, pointer to a char array). You're essentially accessing out of bound memory, thereby invoking undefined behaviour.
Solution: You can simply use the assignment operator =, to copy each element one by one.
That said, if you want to use the answers[i] as string, (as seen in printf("\n%s",answers[i]);) you need to make sure it's null-terminated. A quick way of achieving that would be to initialize the array to 0 upon definition.
Something like
char answers[10][10] = {0}; // ensure the elements are zero-initialized
This question already has answers here:
How do I properly compare strings in C?
(10 answers)
Closed 6 years ago.
I am new in C programming. Can you please advise, what's wrong with my code? It looks like the if statement is not working, and instead it's jumping and printing the else statement.
#include <stdio.h>
#include <stdlib.h>
int main()
{
char profession;
printf("what is your profession? \n");
scanf(" %s", profession);
if(profession==“QA”)
{
printf(“Go and Test\n“);
}
else
{
printf("Do whatever you want");
}
return 0;
}
First of all, you can't compare strings like that in C. use strcmp or strncmp instead.
Secondly, in your code, profession is a char, and you want to put a string (several chars) in it. It won't work. You can create a char * (pointer on a char) (without forgetting to malloc() it) or a char [] (a char array).
Firstly, strings in C are array of characters, so you have to declare profession as a pointer, pointing to an array of characters. So that statement will look like this char* profession, secondly, you have to use a method called strcmp(char* a, char* b) that accepts two char pointers. This will return 0 if they are equal. I will include the answer, but I assume there are better ways of writing this code.
int main() {
char* profession;
char* compare = "QA";
printf("What is your profession?\n");
scanf(" %s", profession);
if(strcmp(profession, compare) == 0) {
printf("Go and Test\n");
} else {
printf("Do whatever you want");
}
return 0;
}
#include <stdio.h>
#include <string.h>
int main(void) {
int number_of_members;
char family[number_of_members][20][number_of_members][20];
char member_name[20];
char birth_state[20];
char family_last_name[20];
printf("What is the last name of the family?\n");
scanf("%s", &family_last_name);
printf("How many members do you want to create?\n");
scanf("%d", &number_of_members);
int const FAMILY_SIZE = number_of_members;
number_of_members = number_of_members -1;
printf("Enter the family member name: \n");
for(number_of_members;number_of_members>-1;number_of_members--)
{
scanf("%s", &member_name);
strcpy(family[number_of_members], member_name);
printf(" %d %s %s\n",number_of_members, member_name, family_last_name);
}
printf("%s, %s ", family[0], family[1]);
return 0;
}
Here is the output:(from Ideone.com)
Ideone.com with code
The input to this code is: Layne , 2 , tim , jim.
When run, it shows the correct index with the name in the array however, once out it will show the last entered name, jim, as family1 and family[0]. Am I not understanding how strcpy() works? or is it a logic error?Some assistance soon would be appreciated!
This is very very wrong
int number_of_members;
char family[number_of_members][20][number_of_members][20];
Because you haven't initialized number_of_members.
Because it doesn't make sense whatsoever, it's not possible that you really need this kind of array.
And yes, if you enable compiler warnings it will hit you in your nose with a stick, because
strcpy(family[number_of_members], member_name);
shouldn't even compile and is undefined behavior since the type of family[number_of_members], is an array of arrays of arrays of char.
strcpy can take an array of char's because it will be automatically converted to a char poitner, and provided that the contents of the array comply with what a c string is, then strcpy() will work correctly, in your case the behavior is undefined because almost surely the '\0' will never be found in the destination pointer.
instead of
int num_of_members;
char family[number_of_members][20][number_of_members][20];
which is not C code, do this
#define MAX_MEMBERS 20
char family[MAX_MEMBERS][20];
which creates a rectangular array of arrays each of 20 bytes long
My code is suppose to get the names of students and the student grade. After that I try to print the student names from the structure that I made and I can only get the grade to print. I get an error when trying to print the string using
printf("%s", test[0].names);
and the error says,
Unhandled exception at 0x0fe113af (msvcr100d.dll) in StudentNamesAndGrades.exe: 0xC0000005: Access violation reading location 0x65736f4a.
But when I use
printf("%d", test[0].studentScores);
It prints out the score of the first student. Here is the entire code because it might be something other than the way I'm trying to print it out.
#include <stdio.h>
#include <string>
/*
this program will get a name of students
and then you will enter the grade for each one :)
*/
struct students
{
char *names;
int studentScores;
};
int main(void)
{
int numStudents = 0;
students *test;
int i;
printf("Enter the number of students in your class: ");
scanf("%d", &numStudents);
test = (students*)malloc(numStudents * sizeof(students));
printf("Enter the names of the %d students\n", numStudents);
for (i = 0; i < numStudents; i++)
{
printf("Enter the name of student %d: ", i + 1);
scanf("%s", &test[i].names);
printf("Enter the students score: ");
scanf("%d", &test[i].studentScores);
}
printf("%d", test[0].studentScores);
printf("%s", test[0].names); // This is where I get a problem :/
return 0;
}
You did not allocate memory for char *names; while taking input at all.
Your struct could be like:
typedef struct students
{
char names[30];
int studentScores;
}students;
Also using fgets is safer than using scanf.
You need to allocate space for the names field, but I would recommend a different approach
struct students
{
char names[100];
int studentScores;
};
and then change the scanf() to
scanf("%99s", test[i].names);
there is another mistake in your first scanf() your are passing the address to the pointer, instead of the pointer.
You should use the address of & operator for the integer, because you need to pass a pointer to an integer for the "%d" specifier, but your names field variable was already a pointer, so no neet to take it's address.
Some other tips you might be interested in
Don't cast the result of malloc, although it seems that you are erroneously using a c++ compiler to compile c code, and in c++ you do need the cast, in c you don't, it makes your code harder to read and other problems which you can read with the most popular c question on Stack Overflow.
Check the return value from malloc, it doesn't matter how unlikely it could fail, since it could theoretically fail, you must check it's return value, which is NULL on failure.