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

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

Related

Converting strings to uppercase to compare with user input in C

I am attempting to create a program that will allow a user to search for a name in a file. The program does this successfully, but then it occurred to me that not everyone will type in the name as it is capitalized in the file. That is, someone may search for "sarah," but as the name is listed as "Sarah" in the file the name will not be found. To get around this I have attempted to convert both strings into upper case at the time of comparison. I am very, very new to teaching myself C, so I am not certain if I am even heading in the right direction. At this point I cannot even get the program to compile as I am getting two errors that say "array initializer must be an initializer list or string literal." I'm assuming that to mean that my syntax is not only invalid but completely in the wrong direction. What would be the best way to approach my goal?
#include <stdio.h>
#include <ctype.h>
#include <string.h>
int main(void)
{
FILE *inFile;
inFile = fopen("workroster.txt", "r");
char rank[4], gname[20], bname[20], name[20];
printf("Enter a name: __");
scanf("%s", name);
int found = 0;
while(fscanf(inFile, "%s %s %s", rank, bname, gname)== 3)
{ char uppername[40] = toupper(name[15]);
char upperbname[40] = toupper(bname[15]);
if(strcmp(uppberbname,uppername) == 0)
{
printf("%s is number %s on the roster\n", name, rank);
found = 1;
}
}
if ( !found )
printf("%s is not on the roster\n", name);
return 0;
}
This two lines are wrong:
char uppername[40] = toupper(name[15]);
char upperbname[40] = toupper(bname[15]);
int toupper(int c); takes an int and returns an int
Because in C string is just an array of chars with a null terminator, so what you can do is to convert each character of the string to uppercase:
for (size_t I = 0; I < strlen(name); I++) {
uppername[I] = toupper(name[I]);
}
uppername[I] = '\0';
Regarding compare, you can use strcasecmp as suggested, which is Posix.
If you want to just use function in the C stdlib, convert the string as above, and then use strcmp.
toupper() works on a single character, not on a string.
No need to convert the input strings. Simple call a string case-insensitive compare.
As C does not have a standard one, it is easy enough to create your own.
int mystricmp(const char *s1, const char *s2) {
// toupper works with unsigned char values.
// It has trouble (UB) with char, when char is signed.
const unsigned char *p1 = (const unsigned char *) s1;
const unsigned char *p2 = (const unsigned char *) s2;
while (toupper(*p1) == toupper(*p2) && *p1) {
p1++;
p2++;
}
int ch1 = toupper(*p1);
int ch2 = toupper(*p1);
return (ch1 > ch2) - (ch1 < ch2);
}
use the following function, which is included in strings.h
int strcasecmp(const char *s1, const char *s2);
in your case change if statement
if(strcmp(uppberbname,uppername) == 0)
to
if(strcasecmp(bname,name) == 0)
and delete
char uppername[40] = toupper(name[15]);
char upperbname[40] = toupper(bname[15]);
Because the function toupper is for converting a character from small to capital, you cannot use it for a string case conversion. But you can string using the same function in this way:
while(name[i])
{
uppername[i]=toupper(name[i]);
i++;
}
while(bname[j])
{
upperbname[j]=toupper(bname[j]);
j++;
}
These statements do our string case conversion. The whole Program:
#include <stdio.h>
#include <ctype.h>
#include <string.h>
int main(void) {
FILE *inFile;
inFile = fopen("workroster.txt", "r");
char rank[4], gname[20], bname[20], name[20], uppername[40], upperbname[40];
printf("Enter a name: __");
scanf("%s", name);
int found = 0, i = 0, j = 0;
while (fscanf(inFile, "%s %s %s", rank, bname, gname) == 3) {
while (name[i]) {
uppername[i] = toupper(name[i]);
i++;
}
while (bname[j]) {
upperbname[j] = toupper(bname[j]);
j++;
}
//char uppername[40] = toupper(name[15]);
//char upperbname[40] = toupper(bname[15]);
if (strcmp(uppername, upperbname) == 0) {
printf("%s is number %s on the roster\n", name, rank);
found = 1;
}
}
if (!found) printf("%s is not on the roster\n", name);
return 0;
}

Substring in C Programming

I just want to extract the particular word from the string.
My program is:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define BUFFER_SIZE 100
int main() {
FILE *f;
char buffer[100];
char buf[100];
int count=0;
char res[100];
f=fopen("1JAC.pdb","rb");
while(fgets(buffer,BUFFER_SIZE,f))
{
if(strncmp(buffer,"ATOM",4)==0 && strncmp(buffer+13,"CA",2)==0 && strncmp(buffer+21,"A",1)==0)
{
strcpy(buf,buffer);
}
printf (buf);
Output of the program is
ATOM 1033 CA LEU A 133 33.480 94.428 72.166 1.00 16.93 C
I just want to extract the word "LEU" using substring. I tried something like this:
Substring(17,3,buf);
But it doesn't work...
Could someone please tell about the substring in C.
Memcpy seems to be best way to do this ...
memcpy( destBuff, sourceBuff + 17, 3 );
destBuff[ 3 ] = '\0';
Please remember to add the null terminators if needed (as I have done in the example).
Also this has been answered before, several times on Stack-overflow
(Get a substring of a char*)
//Use the following substring function,it will help you.
int main(int argc, char *argv[])
{
FILE *filepointer;
char string[1700];
filepointer=fopen("agg.txt", "r");
if (filepointer==NULL)
{
printf("Could not open data.txt!\n");
return 1;
}
while (fgets(string, sizeof(string), filepointer) != NULL)
{
char* temp=substring(string,17,3);/*here 17 is the start position and 3 is the length of the string to be extracted*/
}
return 0;
}
char *substring(char *string, int position, int length)
{
char *pointer;
int c;
pointer = (char*) malloc(length+1);
if (pointer == NULL)
{
printf("Unable to allocate memory.\n");
exit(1);
}
for (c = 0 ; c < length ; c++)
{
*(pointer+c) = *(string+position-1);
string++;
}
*(pointer+c) = '\0';
return pointer;
}
char out[4] = {0};
strncpy(out, buf+17, 3);

Updating string until period is found in C

In this function I am going to be receiving char * words such as
person.vet.blah
and
word.friends.joe
I want to extract the first word. So for the first one I want to extract
person
and the second one I want to extract
word
How can I correctly do this? Here is my code:
char *separate_name(char *machine_name)
{
//iterate until you find period. then return
char absolute_name[1000];
int i;
for (i =0; i < strlen(machine_name); i++)
{
if (machine_name[i] == '.')
absolute_name[i] = machine_name[i];
}
return absolute_name;
}
This is just segfaulting. Any ideas what I should be doing? machine_name is going to be the "person.vet.blah" and then return absolute_name which would be "person"
Fixing your code
As others have pointed out, you can't use absolute_name outside of the function in which it was defined. This is because you're when you return the variable from your function, all that is being returned is a pointer to the beginning of the array. Outside the function, the array itself no longer exists, so the pointer is invalid and you get a segfault if you try and dereference it.
You can get around this by using malloc. Don't forget to free the memory you have allocated when you are done using it.
By the way, as well as changing your loop to a while, I also fixed the check (you were checking machine_name[i] == '.', the opposite to what you wanted).
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *separate_name(char *machine_name)
{
// allocate memory on the heap
char *absolute_name = malloc(strlen(machine_name)+1);
int i = 0;
while (i < strlen(machine_name) && machine_name[i] != '.') {
absolute_name[i] = machine_name[i];
++i;
}
absolute_name[i] = '\0';
return absolute_name;
}
int main()
{
char name1[] = "person.vet.blah";
char *first1 = separate_name(name1);
if (first1 != NULL) {
printf("%s\n", first1);
free(first1);
}
char name2[] = "word.friends.joe";
char *first2 = separate_name(name2);
if (first2 != NULL) {
printf("%s\n", first2);
free(first2);
}
return 0;
}
A better alternative
strtok is the perfect tool for the job:
#include <stdio.h>
#include <string.h>
char *separate_name(char *machine_name)
{
return strtok(machine_name, ".");
}
int main()
{
char name1[] = "person.vet.blah";
char *first1 = separate_name(name1);
if (first1 != NULL) printf("%s\n", first1);
char name2[] = "word.friends.joe";
char *first2 = separate_name(name2);
if (first2 != NULL) printf("%s\n", first2);
return 0;
}
As pointed out in the comments (thanks #John), strtok modifies the string that is passed to it (it replaces the delimiter . by the \0 null byte to mark the end of the string). This isn't a problem here but is something to be aware of.
Output using either program:
person
word
#include <stdio.h>
char *separate_name(const char *machine_name){
static char absolute_name[1000];
int i;
for (i =0; i < sizeof(absolute_name)-1 ; i++){
if(machine_name[i] == '.' || machine_name[i] == '\0'){
absolute_name[i] = '\0';
break;
} else {
absolute_name[i] = machine_name[i];
}
}
return absolute_name;
}
int main(void){
printf("%s\n", separate_name("person.vet.blah"));
printf("%s\n", separate_name("word.friends.joe"));
return 0;
}

how can i save the output of putchar to a variable

I am working on some code that filters text before it is sent further into a program (this code removes everything but all alphanumeric characters and and underscores), the code itself works perfectly except for the fact that I cannot find a way to store the output of of it for use in other parts of the program, If i had to guess, this probably involves saving the stdout from putchar into a variable, but i cannot find much info for doing so online, if someone could point me in the right direction for this I would really appreciate it, thanks!
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int main(void) {
int i;
char *p;
char stg[] = "hello";
for (p = &stg[0]; *p != '\0'; p++) {
if (isalnum(*p) || *p == '_') {
putchar (*p);
}
}
putchar ('\n');
return 0;
}
Perhaps I don't understand your "need" to use putchar() while doing the filtering, but you can filter the input into an output array of chars to use however needed after the filtering as shown below.
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int main(void) {
int i;
char *p;
char stg[] = "hel123*^_lo";
char output[200] = {0x00};
int index = 0;
p = stg;
while( *p )
{
if (isalnum(*p) || *p == '_')
{
output[index++] = (char)putchar(*p);
}
p++;
}
putchar('\n');
printf("[%s]\n", output);
return 0;
}
Output:
hel123_lo
[hel123_lo]
EDIT:
And if you want to just filter the string into an array without displaying the string using putchar() you'd do something like this:
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int main(void) {
int i;
char *p;
char stg[] = "hel123*^_lo";
char output[200] = {0x00};
int index = 0;
p = stg;
while( *p )
{
if (isalnum(*p) || *p == '_')
{
output[index++] = *p;
}
p++;
}
printf("[%s]\n", output);
return 0;
}
And what exactly are you trying to do with the output of the filtered text?
putchar -- int putchar( int ch ); -- returns the character you wrote if successful, EOF if failure.
Nothing prevents you from declaring an int variable, whether a scalar variable, an array element, or a field in a struct, and saving what you wrote. Take note, the return is an int, not a char.
Based on what you've written, you'll probably have to write some code to manage all the outputs you save. In other words, if I'm interpreting your question correctly, you'll be doing more than just saving what you wrote to a variable. You'll probably want to say where in the code you executed the putchar and perhaps even the time. Just guessing though.

Printing a C string in reverse without using pointers?

Is there a way to print a string of fixed size in reverse without using pointers?
#include<stdio.h>
main()
{
char buffer[10];
scanf("%s", buffer);
// need to print buffer in reverse without using pointers??
}
A lovely K&R function to reverse your string in-place before printing it, perhaps?
#include <stdio.h>
#include <string.h>
void strrev(char *s) {
int tmp, i, j;
for (i = 0, j = strlen(s) - 1; i < j; i++, j--) {
tmp = s[i];
s[i] = s[j];
s[j] = tmp;
}
}
int main(int argc, const char *argv[]) {
char buffer[10];
scanf("%s", buffer);
strrev(buffer);
printf("%s\n", buffer);
return 0;
}
#include<stdio.h>
main()
{
char buffer[10];
int n = scanf("%s", buffer);
// print the number of chars written to buffer
if (n != EOF) {
int len = strlen(buffer);
if (len <= 10) {
int i;
for (i = len - 1; i >= 0; i--)
printf("%c", buffer[i]);
}
}
}
Since [] is just syntactic sugar for pointers, here's a version that works completely without pointers, arrays or anything else, just one single int. You didn't say that the string has to be stored somehow. :) (Note that I use fgetc instead of a buffer and scanf).
[jkramer/sgi5k:.../c]# cat rev.c
#include <stdio.h>
#include <stdlib.h>
void read_print();
int main(void) {
fputs("Enter your string, yo! ", stdout);
read_print();
fputs("\nDone!\n", stdout);
return EXIT_SUCCESS;
}
void read_print() {
int c = fgetc(stdin);
if(c != EOF && c != '\n') {
read_print();
fputc(c, stdout);
}
}
[jkramer/sgi5k:.../c]# gcc -o rev rev.c -Wall -W -Os
[jkramer/sgi5k:.../c]# ./rev
Enter your string, yo! foobar
raboof
Done!
Here's a recursive way of doing it; technically, this is using a pointer, but I wouldn't go into language-lawyer mode with such simple tasks.
#include <stdio.h>
/* If you want it printed forward, or backward, or think of another way.. */
typedef enum {
FRONT = 1,
BACK,
} direction;
/* Technically still using a pointer...don't nitpick. */
void echo_string(char buffer[], size_t buflen, direction from)
{
/* An index into the buffer to echo, which will preserve
* its value across subsequent recursive calls.
*/
static size_t index = 0;
/* According to the specified direction, print from the front
* or the back of the buffer. Advance the index (a misnomer, I guess).
*/
if(from == FRONT) {
printf("%c", buffer[index++]);
}
else {
printf("%c", buffer[buflen - ++index]);
}
/* Are there any more characters to echo? Yes? Awesome! */
if(index != buflen) {
echo_string(buffer, buflen, from);
}
}
int main(int argc, char **argv)
{
char buffer[10];
scanf("%s", buffer);
/* Better strlen() than sizeof() here,
* but BEWARE! scanf() is DANGEROUS!
*/
echo_string(buffer, strlen(buffer), BACK);
return(0);
}
reverse(char c[], int len)
{
if( ! (len / 2))
return;
char t = c[0];
c[0] = c[len--];
c[len] = t;
reverse(c, len-1);
}
The error(s) is left as an exercise to the student.
As caf pointed out, we're still using pointers..!
Here's an other way to solve the problem (of reversing a string).
This code snippet (and probably most others) don't respect stuff like utf8. I think signines post demonstrating the K&R way was quite close to mine (:D) so I adapted mine to fit that example (and corrected some things..)
#include <stdio.h>
#include <string.h>
void strrev(char *s) {
size_t len = strlen(s) + 1;
size_t i, j;
for(i = 0; i < len / 2; i++) {
j = len-1 - i-1;
char tmp = s[j];
s[j] = s[i];
s[i] = tmp;
}
}
int main(int argc, const char *argv[]) {
char buffer[10];
scanf("%s", buffer); // Look out for an overflow ;)
strrev(buffer);
puts(buffer);
return(0);
}
You can use strrev to reverse a string.
#include <stdio.h>
#include <string.h>
main()
{
char buffer[10];
scanf("%s", buffer);
strrev(buffer);
printf("%s", buffer);
}
void outstrreverse(const char s[])
{
size_t l=strlen(s);
while( l && s!=&s[--l] )
putchar(s[l]);
if(s[0])
putchar(s[0]);
}
Because of the relationship between C strings, arrays, and pointers the exercise is rather shotty IMHO - the most idiomatic description of a "String" in C is represented by the char*, which is not an array. Your (the OPs) title and post differ in their definitions between string and char[fixed length].
The OP should read and understand this FAQ entry, and between that and the posts here: easily figure out a solution—as well as defend it to the teacher/judge if need be.
I'll comment on this: never use scanf("%s", buffer) to populate a fixed length string. If you must use scanf() to do it, please use a field width specifier: e.g. scanf("%9s", buffer); if buffer is an [10], you want a specifier of 9 because of how scanf fills the buffer: otherwise you must beware the dragons! You could also scanf by character and evade the issue with a loops bounds, but that would likely be less efficient.
#include <stdio.h>
#include <conio.h>
void reverse(char a[], int s, int sc );
void reverse(char a[], int s, int sc ){
if ((sc-s)<(s-1))
{
a[sc-s]^=a[s-1];
a[s-1]^=a[sc-s];
a[sc-s]^=a[s-1];
reverse (a, s-1, sc) ;
}
}
void main (){
char a[]="ABCDEFG";
reverse(a, 7, 7);
printf("%d",a);
getch(); //i just use it to freeze the screen
}

Resources