Null When Passing String - c

I got this output "Hospital (null) ΓÇô Report for COVIC19 ΓÇô Community Visit"
I'm trying to printout the name of the hospital from the function readHospital() but all I got for the output is these weird looking text. So sorry I'm very new to coding.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <conio.h>
char readHospital();
void intro(char a);
int main() {
char hospital_name;
hospital_name = readHospital();
intro(hospital_name);
}
char readHospital() {
char a[100];
printf("Enter Hospital Name: ");
fgets(a, 100, stdin);
return a;
}
void intro(char hospital_name) {
printf("Hospital %s – Report for COVIC19 – Community Visit", hospital_name);
}

I've changed your code, The readHospital function that you are using in your code is not a correct function for reading the input string from the user and returning it.
Instead, you can use the readNewString function that I've written.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <conio.h>
char * readNewString();
void intro(char a[100]);
int main() {
char * hospital_name;
hospital_name = readNewString();
intro(hospital_name);
}
char *readNewString(void) {
char buffer[1024];
if (!fgets(buffer, sizeof buffer, stdin)) {
return NULL; // read failed, e.g., EOF
}
int len = strlen(buffer);
if (len > 0 && buffer[len - 1] == '\n') {
buffer[--len] = '\0'; // remove the newline
// You may also wish to remove trailing and/or leading whitespace
} else {
// Invalid input
//
// Depending on the context you may wish to e.g.,
// consume input until newline/EOF or abort.
}
char *str = malloc(len + 1);
if (!str) {
return NULL; // out of memory (unlikely)
}
return strcpy(str, buffer); // or use `memcpy` but then be careful with length
}
void intro(char hospital_name[100]) {
printf("Hospital %s – Report for COVIC19 – Community Visit", hospital_name);
}

Please note that hospital_name is of char type and you return a string, char list char*

Related

Is there a way combine a specific number of chars from fgetc?

I have found some information about strcat and experimented with it but it doesn't work the way i expected for example :
char a = 'a', b = 'b';
strcat(a,b);
printf("%c", a);
this will produce an error "initialization of 'char' from 'char *' makes integer from pointer without a cast". Is there a way to unite chars until the wanted word is complete and store it in 1 variable? Or am i going completely wrong about this. The purpose of the code is to read an xml file and build a tree with the tags.
Any help is or advice is very much appreciated.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
int count = 0;
char c, word;
FILE *file = fopen("example.xml", "r");
if (file == NULL) {
return 0;
}
do {
c = fgetc(file);
if (c == '<') {
count = 1;
}
if (c == '>') {
count = 0;
printf(">");
}
if (count == 1) {
printf("%c", c);
}
if (feof(file)){
break ;
}
} while(1);
fclose(file);
return(0);
}
I'm not sure exactly what you're trying to accomplish, but you could try something like the following, which will print every <tag>, i.e., every string in the file between <...>'s , and will also accumulate them in an array of strings called tags[]. And note that you'd might want to add checks that avoid going over the 99 chars/tag and 999 tags total. But if this isn't anything like what you're actually trying to do, maybe clarify the question.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
int ntags=0, ichar=0,nchars=0;
char c='\000', tags[999][99];
FILE *file = fopen("example.xml","r");
if (file==NULL) return(0);
while((ichar=fgetc(file))!=EOF) {
c = (char)ichar;
if (nchars==0 && c!='<') continue;
tags[ntags][nchars++] = c;
if (c=='>') {
tags[ntags][nchars] = '\000';
printf("tag#%d = %s\n",ntags+1,tags[ntags]);
nchars=0; ntags++; }
}
/* do you now want to do anything with your tags[] ??? */
fclose(file);
return(0);
}
You are trying to use a function, those parameters are char *
char *strcat(char *dest, const char *src)
but you gave strcat a char but it wants a char*
int main()
{
char str1[20] = "this";
char str2[] = "is";
strcat(str1, str2);
printf("%s", str1);
return 0;
}
this is the way i thinkt you want it

How do I convert a string to uppercase using the standard library?

I am trying to use a for loop with ASCII table to make every character in the string uppercase one by one by subtracting the letter number with 32. but I cant use the int i in the char str and str2. how can I do this?
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#define STRLEN 200
void string_lower() {
}
void string_upper(char str) {
char str2;
int length = strlen(str);
for (int i = 0; i < length; i++) {
str2[i] = str[i - 32];
}
}
int main() {
char word[STRLEN] = { 0 };
char word1 = 97;
printf("Write a word");
fgets(word, STRLEN, stdin);
string_upper(word);
return 0;
}
You can use toupper() to uppercase one character at a time. This will work for single byte character sets such as ASCII, but not for the UTF-8 encoding in general use today for non English scripts.
Here is a modified version:
#include <ctype.h>
#include <stdio.h>
#define STRLEN 200
char *string_upper(char *str) {
for (size_t i = 0; str[i] != '\0'; i++) {
str[i] = toupper((unsigned char)str[i]);
}
return str;
}
int main() {
char word[STRLEN];
printf("Enter a word: ");
if (fgets(word, STRLEN, stdin)) {
printf("%s", string_upper(word);
}
return 0;
}
The argument must be cast as (unsigned char)str[i] because str[i] has type char and tolower() like all functions and macros from <ctype.h> is only defined for values of the type unsigned char and the special negative value EOF. As char may be signed on some platforms, passing it directly to tolower() would have undefined behavior for negative values such as 'é' and 'ÿ'.
If you just want to make a function to convert your String to upper, maybe you can refer to the below example.
#include <stdio.h>
#include <ctype.h>
#define STRLEN 200
void string2upper(char *str){
int cursor=0;
while(*(str+cursor)!='\0'){
*(str+cursor) = toupper(*(str+cursor));
cursor++;
}
}
void main() {
char String1[STRLEN];
printf("Write a word:\n");
fgets(String1, STRLEN, stdin);
printf("Before : %s\n", String1);
string2upper(String1);
printf("After : %s\n", String1);
}
For the toupper() function, I think you can refer to this Link.
That has a detailed explanation and simple example to understand.
I think to know the function detail is better than only using~

Writing concise code in C

strcat(msg, ": ");
strcat(msg, buf);
Is there a way to do this in one line? I want to make my code cleaner and reduce clutter
Instead of doing multiple concatenations, try creating a formatted string. Try something like this:
#include <stdio.h>
#include <string.h>
int main()
{
char *before_colon = "Text before colon";
char *after_colon = "Text after colon";
// Make a string that is the size of both formatted strings, plus a
// character for the space, colon, and null character.
char final_string[strlen(before_colon) + strlen(after_colon) + 3];
// This works just like any other C formatted function (i.e printf, scanf)
sprintf(final_string, "%s: %s", before_colon, after_colon);
printf("%s\n", final_string);
}
output:
Text before colon: Text after colon
Here's a modified code of Charlie Sale with its own function to count characters in the string. Thus, StrLen is called in array declaration.
#include <stdio.h>
#include <string.h>
int StrLen(char* PtrFirstChar)
{
int n = 0;
while(*(PtrFirstChar++)) // will evaluate to FALSE when '\0' reached
n++;
return n;
}
int main()
{
char *before_colon = "Text before colon";
char *after_colon = "Text after colon";
// Make a string that is the size of both formatted strings, plus a
// character for the space, colon, and null character.
char final_string[StrLen(before_colon) + StrLen(after_colon) + 3];
// This works just like any other C formatted function (i.e printf, scanf)
sprintf(final_string, "%s: %s", before_colon, after_colon);
printf("%s\n", final_string);
}
You could write your own variant of strcat!
I'm going to use strncat as a basis because strcat is a really bad idea:
#include <stddef.h> /* for size_t */
#include <stdarg.h> /* for va_* */
char *
mstrncat(char *d, size_t maxlen, ...)
{
va_list ap;
va_start(ap, maxlen);
char *ret = d;
/* Fast-forward */
for (; *d && maxlen; ++d, --maxlen);
/* Reserve a space for the terminator */
if (maxlen)
--maxlen;
const char *p;
/* Concatenate parameters one by one */
while (maxlen && (p = va_arg(ap, const char *))) {
while (*p && maxlen--)
*d++ = *p++;
}
/* Terminate the string */
*d = 0;
va_end(ap);
return ret;
}
You can use it like this:
#include <stdio.h>
int
main()
{
char test[128]="test";
mstrncat(test, sizeof(test), "1", "two", "3", NULL);
puts(test);
return 0;
}

conflicting types for function returning a char array

Here's my code:
#include <stdio.h>
#include <string.h>
char input_buffer[1000];
void get_substring(){
int i;
int length;
printf("Please enter a string:\n");
scanf("%[^\n]s", input_buffer);
printf("Index of first character of substring:\n");
scanf("%d", &i);
printf("Length of substring:\n");
scanf("%d", &length);
printf("Substring is %.*s ", length, input_buffer + i);
}
int main(void) {
// your code goes here
//get_substring(0,4);
get_substring();
return 0;
}
That's my current code, I want to return a pointer of the input, instead of just displaying the substring. Sorry for the confusion everyone.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char* getSubstring(char* str,size_t start, size_t length)
{
// determine that we are not out of bounds
if(start + length > strlen(str))
return NULL;
// reserve enough space for the substring
char *subString = malloc(sizeof(char) * length);
// copy data from source string to the destination by incremting the
// position as much as start is giving us
strncpy(subString, str + start, length);
// return the string
return subString;
}
int main(int argc, char* argv[])
{
char *str = "Hallo Welt!";
char *subStr = getSubstring(str,0,20);
if(subStr != NULL)
{
printf("%s\n",subStr);
free(subStr);
}
}
This solution should give you a hint how you would start with such a problem.

C fgets and sscanf in loop : prevent useless looping

I have a problem with looping and fgets and sscanf to get the input.
I know to problem is from the size of the malloc with the input. If the user enter number larger than the malloc i want to ask again to enter a new number.
But in this code, if an user enter a too large number, it's looping lot of time (size of the word / 8) i think.
How to ask again to the user to enter new number without looping 4 times for example.
See the example i made with big number.
The idea was to free the input after the loop but it's doesn't works. Any ideas ?
There is my code :
#include <stdio.h>
#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>
#include <stdbool.h>
#include <string.h>
int main(void) {
char x[8];
char y[8];
int result = 0;
char *input=malloc(sizeof(char)*8);
bool answer = 0;
char *pos;
while(!answer) {
fgets(input, sizeof(input)-1, stdin);
//remove the /n from fgets
if ((pos=strchr(input, '\n')) != NULL)
*pos = '\0';
result = sscanf (input, "%s %s", x, y);
printf("%d\n", result);
if(result < 2) {
fprintf(stderr, "There is an error with the number you give, try again\n");
} else {
printf("%s\n", x);
printf("%s\n", y);
}
}
return 0;
}
And the output for : "01 01"
01 01
2
01
01
Output for : 000000005 000000005
0000000000005 000000000000005
1
There is an error with the number you give, try again
1
There is an error with the number you give, try again
2
5
0000
1
There is an error with the number you give, try again
1
There is an error with the number you give, try again
fgets() doesn't throw away the rest of the line when it's longer than its buffer. You have to do it yourself.
If you look at this code I frequently use with fgets, you'll see the two tasks separated, and in which circumstances which one is done:
/*Returns 0 if OK, a negative value if EOF.*/
int fpurge(FILE *f)
{
int c;
while((c=fgetc(f))!=EOF && c!='\n')
{ }
return (c==EOF ? -1 : 0);
}
/* Returns a nonzero value if found, zero if not. */
int truncate_newline(char *str)
{
int bRet=0;
if(str!=NULL)
{
char *pNewLine = strchr(str, '\n');
if(pNewLine!=NULL)
{
bRet = 1;
*pNewLine = '\0';
}
}
return bRet;
}
/* Returns 0 if buffer is full, a positive value if line is complete,
a negative value if EOF (implies buffer full). */
int fclean(char *str, FILE *f)
{
int ret = 1;
if(!truncate_newline(str))
ret = fpurge(f);
return ret;
}
You can see that your own code does the truncate_newline part, but not the "throw away the rest of the line" (here in the function fpurge) part.
If you change your code thusly, it should work:
#include <stdio.h>
#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>
#include <stdbool.h>
#include <string.h>
#define BUFFER_SIZE 8
int main(void) {
char x[BUFFER_SIZE];
char y[BUFFER_SIZE];
int result = 0;
char *input=calloc(BUFFER_SIZE, sizeof(char));
bool answer = 0;
char *pos;
while(!answer) {
fgets(input, BUFFER_SIZE, stdin);
//remove the /n from fgets
if ((pos=strchr(input, '\n')) != NULL)
*pos = '\0';
else
{
int c;
while((c=getchar())!='\n' && c!=EOF) {}
}
result = sscanf (input, "%s %s", x, y);
printf("%d\n", result);
if(result < 2) {
fprintf(stderr, "There is an error with the number you give, try again\n");
} else {
printf("%s\n", x);
printf("%s\n", y);
}
}
return 0;
}
Or simply replace the whole if() with fclean(input, stdin);

Resources