array of character in C - c

I have a question simple like that: Let user enter some words from keyboard,one word per line until a '.' (period) entered then print out result, for example:
Enter a word: word1
Enter a word: word2
Enter a word: .
You have entered 2 word(s):
word1
word2
OK here my try but when I run it said file has stopped working after let me enter first word
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <string.h>
int main ()
{
char *word[50]; //each word has maximum 49 character
int i=0, number_of_word;
do
{
printf ("Enter a word: ");
scanf("%s", &word[i]);
i++;
}
while (word[i][0]!='.');
number_of_word =i;
printf ("You entered %d word(s):\n", number_of_word);
for (i=0; i<number_of_word; i++)
{
printf("%s\n", &word[i]);
}
return 0;
}
-----------------------------------------------------------------------
EDIT 1:
OK I try this, it worked but I am still looking for best way to declare an unknown size array of character string since I don't know neither how many word user may enter nor how many letter of each word, in C++ it may called dynamic allocation array, I have no idea how to do it in C
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <string.h>
int main ()
{
char word[20][50]; //array has maximum 20 words, each word maximum 50 character
int i=0, number_of_word;
do
{
printf ("Enter a word: ");
scanf("%s", word[i]);
i++;
}
while (word[i-1][0]!='.');
number_of_word =i-1;
printf ("You entered %d word(s):\n", number_of_word);
for (i=0; i<number_of_word; i++)
{
printf("Word %d is %s\n", i, word[i]);
}
return 0;
}

You are not assigning any memory to store the individual strings, so your program invokes undefined behaviour.
This:
char *word[50];
defines an array of 50 pointers, but no further storage.
And when you do this:
scanf("%s", &word[i]);
you're writing into the pointer array.

#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <string.h>
int main () {
char *word[50]; //each word has maximum 50 word
char enter_word[50];//maximum 49 character
int i=0, number_of_word;
while(1){
printf("Enter a word: ");
scanf("%49s", enter_word);
if(*enter_word == '.')break;
word[i++]=strdup(enter_word);
}
number_of_word = i;
printf ("You entered %d word(s):\n", number_of_word);
for (i=0; i<number_of_word; i++){
printf("%s\n", word[i]);
}
for(i=0;i<number_of_word; ++i)
free(word[i]);
return 0;
}

When you declare
char *word[50];
You have 50 char pointers pointing to random memory. What you want is something like this:
char word[50][50];
Note that you can have only 49 words (and the '.'), and each can have less than 50 characters (don't forget the \0, so a word with 50 chars will overflow).
And you will want to change your scanf call to something like:
scanf("%s", word[i]);
Note that you do not need the &, since word[i] is already a pointer.

char *word[50];
You have an array of 50 pointers. You want an array of 50 byte chunks. How many words do you want to read? If you know the maximum, you can allocate the space in advance. If you don't, you need something like a linked list of strings, to which you can append a new item when you read it.

Its your printf Call. Remember to add the end character \0 to the end of the word. Printf when printing strings prints everything in the char array till it reads an end character \0
BasicAlly... Hos should printf know how long the word is and when it should stop printing?(Right now it continues forever)

You've done nothing to allocate memory for the individual strings.
Char *word[50] just declares a pointer to one array of char pointers.
EDIT
I'll try to illustrate this here with some pseudo code...formatted code on a phone is nearly impossible :) Given a prior char * input[50]:
char * nextString;
bool entering=true;
do{
nextString =calloc(50);
// enter the string to nextString
if (nextString[0] != '.'){
input[i] = nextString;
i++;
} else{
entering=false;
}
}
}while(entering)

"char *word[50]" have done nothing to allocate the memory for the individual string.
you should allocate it by using the function of alloc

you just try to use "%[^\n]" place of "%s" in scanf().
because "%s" stores characters until it found first space in the string.
try this with your very first asked Program
May its help to you.

Related

How do I request characters from a user, and then print the size of the characters?

I'm very new to C, any help would be greatly appreciated.
I can't use the <string.h> or <ctype.h> libraries.
This is the code I have:
int main(void)
{
char character;
printf("Introduce characters: ");
scanf(" %c", &character);
printf("\nSize of character: %d", sizeof(character)/sizeof(char));
return 0;
}
This only prints 1 as the size.
I read in another post that the problem was that initializing character by char character; would only let me store 1 single character. So, I modified it to be an array:
int main(void)
{
char character[10];
printf("Introduce maximum 10 characters: ");
scanf(" %s", character);
printf("\nSize of character: %d", sizeof(character)/sizeof(char));
return 0;
}
The problem now is that by doing character[10], it prints out that the size is 10. How would I go about fixing this?
sizeof(character)/sizeof(char) gives you the size of the array you declared, not the size of what the user has entered.
sizeof(character) gives the size of the entire array in bytes
sizeof(char) gives the size of a single character in bytes
So, when you do sizeof(character)/sizeof(char), you get the actual size (i.e. number of elements) of your array. What you are trying to achieve can be done with strlen(). But since you can't use <string.h>, you can write it yourself:
int strlen2(char *s)
{
int size;
for (size = 0; s[size]; size++)
;
return size;
}
Then use it like:
#include <stdio.h>
int main(void)
{
char character[10];
printf("Introduce maximum 10 characters: ");
scanf("%s", character);
printf("\nSize of character: %d", strlen2(character));
}
strlen2() counts the number of characters of your string, it stops counting when it encounters the first \0 character (null terminator).
Avoid using scanf() to read input
Your code is prone to bugs. If the user enters a string more than 9 characters long (don't forget the \0 is added at the end of your string), you'll get a buffer overflow, because character is only supposed to contain 10 characters. You would want to limit the number of characters read into your string:
scanf("%9s", character); // Read only the first 9 characters and ignore the rest
Moreover, scanf() is used to parse input, not to actually read it. Use fgets() instead:
#include <stdio.h>
#include <string.h> // for strcspn()
int main(void)
{
char character[10];
printf("Introduce maximum 10 characters: ");
if(!fgets(character, 10, stdin)) {
fprintf(stderr, "Error reading input.\n");
return 1;
}
character[strcspn(character, "\n")] = '\0'; // fgets() reads also `\n` so make sure to null-terminate the string
printf("\nSize of character: %zu", strlen(character));
}
fgets() accepts three arguments:
The first one is the array in which you want to store user input
The second one is the size of your array
The third one is the file stream you want to read from
It returns NULL on failure so you should check that as well.
Well if you can't use any headers, maybe you can create a custom strlen() function.
strlen() pretty much counts all character until the '\0' character is found. '\0' is used to signify the end of string and is automatically appended by scanf("%s",...).
#include <stdio.h>
size_t ms_length(const char *s)
{
size_t i = 0;
for (; s[i] != '\0'; i++)
;
return i;
}
int main(void)
{
char *str = "hello";
printf("%zu\n", ms_length(str));
return 0;
}
And if you want to be pedantic, you might even want to check the return value of scanf(), for input errors and also apply a limit to the character to be read to avoid a buffer overflow.
if (scanf(" %9s", character) != 1) /* 9 characters + 1 reserved for \0 */
{
/* handle error */
return 1;
}

How can I put a user input value into strncpy?

So, I am trying to write an strncpy function. I want user to input the number of characters to be copied from source. I am doing something wrong, but I can't understand what. This is what I tried to do:
#include <stdio.h>
#include <string.h>
#define ARR_SIZE 20
int main() {
char string[ARR_SIZE];
int n, m;
char s1[4], s2[4], nstr[m];
printf("Enter the string:");
gets(string);
printf("The length of the string is: %ld\n", strlen(string));
strcpy(s1, s2);
printf("The original string is: %s\n", string);
printf("The copy of the original string is: %s\n", string);
printf("How many characters do you want to take from this string to create another string? Enter: \n");
scanf("%d", &n);
strncpy(nstr, s1, m);
printf("%s\n", nstr);
}
(On top I tried some strlen and strcpy functions.)
EDIT: I totally forgot to write what was the problem. Problem is I can't get the new string which is named nstr in my code. Even though I printed it out.
first of all, the whole code is just a bad practice.
Anyway, here is my take on your code which copies n characters of an input string to string_copy
#include <stdio.h>
#include <string.h>
#define ARR_SIZE 20
int main() {
char string[ARR_SIZE];
int n;
printf("Enter the string:");
gets(string);
printf("The length of the string is: %ld\n", strlen(string));
printf("The original string is: %s\n", string);
printf("How many characters do you want to take from this string to
create another string? Enter: \n");
scanf("%d", &n);
if(n > strlen(string)){
n = strlen(string);
printf("you are allowed to copy maximum of string length %d\n", n);
}
char string_copy[n];
strncpy(string_copy, string, n);
printf("%s\n", string_copy);
}
note that using deprecated functions such as gets() isn't safe. use scanf() or fgets() instead.
refer to why you shouldn't use gets()

Don't have right output while comparing chars

#include <stdio.h>
#include <stdlib.h>
struct patients{
char last_name[15];
int passport_number;
char disease[30];
char doctors_last_name[15];
};
int main (){
int n,i;
char enter_doctors_last_name [15];
struct patients mas_struct[3]={{"Ivanov",5457401,"COVID-18","Davis"},{"Petrov",2864228,"COVID-19","Davis"},{"Petrova",63863380,"COVID-19","Dixon"}};
printf("\nPatients:");
printf("\n Last name | Passport number | \tDisease | Doctor's last name ");
for (i=0;i<3;i++)
printf("\n %s \t%d \t%s \t%s",mas_struct[i].last_name,mas_struct[i].passport_number,mas_struct[i].disease,mas_struct[i].doctors_last_name);
printf("\n");
printf("\nEnter doctor's last name:");
scanf("%s", enter_doctors_last_name);
printf("\nPatients:");
for (i=0;i<3;i++)
if(mas_struct[i].doctors_last_name == enter_doctors_last_name)
printf("\n %s \t%d \t%s \t%s",mas_struct[i].last_name,mas_struct[i].passport_number,mas_struct[i].disease,mas_struct[i].doctors_last_name);
return 0;
}
Got trouble in comparing chars, it doesn't work and I can't come up with the right words for googling it.
In the last lines when I type "Davis" or "Dixon" for enter_doctors_last_name
Output is just Patients
I also tried to use gets function
You can't compare strings with == operator, use strcmp instead:
if (!strcmp(mas_struct[i].doctors_last_name,enter_doctors_last_name)){/*...*/}
scanf with "%s" specifier is very unsafe use "%14s" instead, the -1 character is to reserve space for the null-terminator.
If you need names with more than 1 word you should use "%14[^\n]", reads everything until the newline character is found.
You should use strcmp() function for comparing strings.

Character Pointers with Palindrome Checker in C

This is code I wrote that checks if a string is a palindrome or not. I need to revise this code so that it uses character pointers in it. Could someone give me some suggestions/tips...or show me how to do that? Thanks
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int main(){
char string1[20];
int i, length;
int flag = 0;
printf("Enter a string: ");
scanf("%s", string1);
length = strlen(string1);
for(i=0;i < length ;i++){
if(toupper(string1[i]) != toupper(string1[length-i-1])){
flag = 1;
break;
}
}
if (flag)
printf("%s is not a palindrome \n\n", string1);
else
printf("%s is a palindrome \n", string1);
return 0;
}
In your code you use string1[i] to access the current element from the beginning of the string, and string1[length-i-1] to access the current element from the end of the string. You could create two pointers, pb and pe, and then move them toward each other.
To define pointers, use this:
char *pb = &string1[0]; // Or just string1, compiler will convert it to pointer
char *pe = &string1[length-1];
To advance the pointers toward each other, use pb++ and pe--.
To see if the pointers have not crossed each other , check that pb < pe. Currently, your program checks the string twice; there's no need to do that - you can stop as soon as pe becomes less than or equal to the pb.
To access the character pointed to by the current pointer, use
toupper(*pb) != toupper(*pe)
You can combine the check with advancing the pointers, like this:
toupper(*pb++) != toupper(*pe--)
Note: it is not safe to use %s, because when users enter more characters than fits in your string1 buffer overrun results. You should specify the length of the buffer, like this:
scanf("%19s", string1); // Leave one char for null terminator
I'm not sure I completely understand the question, but I think this answers it. You actually are using character pointers. char string1[20] is the same as char *string1. The difference is that you've basically assigned the pointer to a block of memory. You could access the string in this way.
char string[20] = "foo";
printf("%c\n", string[0]); // will print 'f'
printf("%c\n", *string); // will also print 'f'
printf("%c\n", string[1]); // will print the first 'o'
printf("%c\n", *(string + 1)); // will also print the first 'o'
with char * it goes like this
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int main()
{
char string1[20];
int i, length;
int flag = 0;
printf("Enter a string: ");
scanf("%s", string1);
length = strlen(string1);
char *start=string1;
char *end=&string1[length-1];
//only check upto half
for(i=0;i <= (length-1)/2 ;i++)
{
if(toupper(*(start+i)) != toupper(*(end-i)))
{
flag = 1;
break;
}
}
if (flag)
printf("%s is not a palindrome \n\n", string1);
else
printf("%s is a palindrome \n", string1);
return 0;
}
cant we just copy the original string to another array, and then use strrev() to reverse the copied string and then finally compare the original string with the reversed string?
Like this
1.get new string
2.copy string to new array
3.reverse the copied string using strrev
4.use strcmp to check if both are same or not?
this seemed easier
(i am a beginner so please correct me if i am wrong)

Passing pointers to string arrays to toupper() in C

I'm trying to pass a pointer array of strings to function toupper() in C.
main() {
char *choice[1];
scanf("%s", choice);
printf("%s", toupper(&choice[0]));
}
I always type in a lowercase word such as "modify" to test it. Different variations of this, such as toupper(*choice[0]) or toupper(*choice) or mixtures of them all, including &, have either thrown an error or returned the same lowercase "modify". Any suggestions?
To start with array of char pointers having one element doesn't make much sense to me since it will only point to one string.Why not declare a char array if you just want a single string?
Prototype of toupper is this:
int toupper( int ch );
It doesn't take an array.
You can try like this :
#include <stdio.h>
#include <ctype.h>
int main()
{
char str[25];
int i = 0;
setbuf(stdout,NULL);
printf ("enter the name \n");
fgets (str,sizeof str-1, stdin);
printf ("the name entered in upper case is :\n");
while (str[i])
{
int c = str[i];
printf ("%c",toupper(c));
i++;
}
return 0;
}
NOTE- Do not use scanf for taking strings try fgets , its better.
Before you call scanf, you need to allocate some space for the characters to be stored in. You only allocate a single pointer and then you don't even set it to point to anything. Similarly, toupper returns the converted character, which is not a string, so passing it to printf through %s is also wrong.
Something like this should serve the purpose.
#include<stdio.h>
#include<ctype.h>
void StrToUpper(char *str)
{
while(*str != '\0')
{
*str = toupper(*str);
str++;
}
}
int main()
{
char *choice[1];
choice[1] = new char[10];
scanf("%s", choice[1]);
StrToUpper(choice[1]);
printf("%s", choice[1]);
return 0;
}
In the program, you have array of pointers.
So:
Allocate memory for your string
call toupper(choice[0][0]);
toupper takes only a character value (between 0 and 255), not a pointer or array.

Resources