Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
In my code, I'd like to use string that denotes Will, Bob, Billy, Ryan or Ed instead of int. Specifically, using N strings S[1],S[2]...S[N] where S[I] the names above.
And also, input N is limited as following: (1 ≤ N ≤ 100,000)
#include <stdio.h>
int main(void)
{
int input_num=0;
int isWill = 0;
int isBob = 0;
int isBilly = 0;
int isRyan = 0;
int isEd = 0;
int n=0;
scanf("%d", input_num);
printf("%d", input_num);
for(n;n<input_num;n++)
{
char tmp[100,000];
scanf("%s", tmp);
if(tmp == "Will")
isWill = 1;
else if(tmp == "Bob")
isBob = 1;
else if(tmp == "Billy")
isBlue = 1;
else if(tmp == "Ryan")
isRyan = 1;
else if(tmp == "Ed")
isEd = 1;
}
//end of input
if(isWill == 0)
printf("Will\n");
if(isBob == 0)
printf("Bob\n");
if(isBilly == 0)
printf("Billy\n");
if(isRyan == 0)
printf("Ryan\n");
if(isEd == 0)
printf("Ed\n");
return 0;
}
To compare strings, you need to use the strcmp library function, which returns 0 if the two argument strings are equal:
if ( strcmp( tmp, "Will" ) == 0 )
// tmp contains the string "Will"
If you want an array of strings, you can do it one of two ways. You can declare a 2d array, where the first dimension is tne number of names, and the second dimension is the max length of a name:
char names[NUMBER_OF_NAMES][MAX_NAME_LENGTH+1];
To copy a string, use strcmp:
strcmp( names[0], "Will" );
strcmp( names[1], "Bob" );
// etc.
Or, you can declare a 1D array, where each element is a pointer to a string:
char *names[NUMBER_OF_NAMES];
names[0] = "Will";
names[1] = "Bob";
Note that you're assigning a pointer value to names[i]; you're not copying the string contents to names[i].
Finally, C doesn't recognize integer literals like 100,000; you'll want to declare your tmp buffer as
char tmp[100000];
although that's somewhat large for a string buffer.
Several things not quite as i would write them.
I had some minutes to spare and wrote a compiling example.
Maybe your problems can be solved by this.
char * colortext[] =
{
"unknown",
"white",
"black",
"blue",
"red",
"yellow"
};
typedef enum color {
unknown = 0,
white,
black,
blue,
red,
yellow
};
typedef struct
{
int number;
char name[200];
color team;
}Player;
typedef struct
{
char * name;
color team;
}Autoassign;
Autoassign autoassign[] =
{
{"Will", white},
{"Bob", black},
{"Billy", blue},
{"Ryan", red},
{"Ed", yellow}
};
int autoassignLength = sizeof(autoassign) / sizeof(autoassign[0]);
int Player_print(Player * player)
{
int e = 0;
printf("\n");
printf("Player %i Profile:\n", player->number);
printf("Name: '%s'\n", player->name);
printf("Team: '%s'\n", colortext[player->team]);
printf("\n");
return e;
}
int Player_scan(Player * player, int number)
{
int e = 0;
int i;
printf("Input Player Name: ");
scanf("%s", player->name);
player->number = number;
player->team = unknown;
for(i = 0; i < autoassignLength; ++i)
{
if(0 == strcmp(player->name,autoassign[i].name))
{
player->team = autoassign[i].team;
break;
}
}
return e;
}
int main(int argc, char ** argv)
{
int i;
int input_num, n;
Player players[10];
printf("How many Players? ");
scanf("%d", &input_num);
for(n = 0; n < input_num ; n++)
{
Player_scan(&players[n], n+1);
}
for(n = 0; n < input_num ; n++)
{
Player_print(&players[n]);
}
return 0;
}
If you want to make compare strings that's not the way to go.
Use string.h library to be able to use the function strcmp .
To use this functions type strcmp(string1, string2)
Just remember that strcmp will return 0 if the strings are equal.
So what you want to do is use if(!strcmp("Will", tmp)) to enter the if when the strings are the same.
You also need to change char tmp[100,000] to char tmp[100000], for this is the supported format in C.
Hope this helps.
Related
I am sorry if this sounds confusing, I will try to be as clear as possible. I have an array of structs, where the array stores a struct that I have defined as a Business Card. However, before adding any new business cards into the array, I have to store the structs in ascending order based on the integer value of the Employee ID.
Here is the struct:
typedef struct{
int nameCardID;
char personName[20];
char companyName[20];
} NameCard;
Hence, I tried to use relational operators to compare between the values of the ID and copy it in ascending order to another temporary array I named fakeHolder, before finally copying over to the actual array. However, I can't seem to understand why it is not in order after inputting my data as ID 9, 7, 5.
Here is my helper function:
int addNameCard(NameCard *nc, int *size){
int i = 0;
// Why is this a pointer?
NameCard fakeHolder[10];
char dummy[100];
char *p;
printf("addNameCard():\n");
if(*size == MAX){
printf("The name card holder is full");
// To quit the program
return 0;
}
// Keeps it to Fake Name Card Holder First
printf("Enter nameCardID:\n");
scanf("%d", &fakeHolder->nameCardID);
scanf("%c", &dummy);
printf("Enter personName:\n");
fgets(fakeHolder->personName, 20, stdin);
if(p = strchr(fakeHolder->personName, '\n')){
*p = '\0';
}
printf("Enter companyName:\n");
fgets(fakeHolder->companyName, 20, stdin);
if(p = strchr(fakeHolder->companyName, '\n')){
*p = '\0';
}
// Compare the ID value
for(int j = 0; j < *size; j += 1){
if(fakeHolder->nameCardID == (nc+j)->nameCardID){
printf("The nameCardID has already existed");
}
else if(fakeHolder->nameCardID < (nc+j)->nameCardID){
fakeHolder[(j+1)].nameCardID = (nc+j)->nameCardID;
strcpy(fakeHolder[(j+1)].personName,(nc+j)->personName);
strcpy(fakeHolder[(j+1)].companyName, (nc+j)->companyName);
}
}
*size += 1;
// Transfer to the Actual Name Card Holder
for(int k = 0; k < *size; k += 1){
(nc+k)->nameCardID = fakeHolder[k].nameCardID;
strcpy((nc+k)->personName, fakeHolder[k].personName);
strcpy((nc+k)->companyName, fakeHolder[k].companyName);
}
printf("The name card has been added successfully\n");
return 0;
}
Your current code has several problems, and you can rewrite it to be much more maintainable and easier to work with. For example,
i (in int i = 0;) is not being used
scanf("%c", &dummy); is there, I assume, to remove trailing \n - but a 100-char buffer for a single character to read is... surprising. See scanf() leaves the new line char in the buffer for lots of discussion on different approaches to "trailing stuff after integer".
splitting addNameCard into 2 functions, one to actually request a NameCard and another to insert it into the array, would divide up responsibilities better, and make your program easier to test. Avoid mixing input/output with program logic.
The question you ask can be solved via the standard library qsort function, as follows:
#include <stdlib.h>
typedef struct{
int nameCardID;
char personName[20];
char companyName[20];
} NameCard;
void show(NameCard *nc, int n) {
for (int i=0; i<n; i++, nc++) {
printf("%d,%s,%s\n",
nc->nameCardID, nc->personName, nc->companyName);
}
}
// comparison functions to qsort must return int and receive 2 const void * pointers
// they must then return 0 for equal, or <0 / >0 for lower/greater
int compareCardsById(const void *a, const void *b) {
return ((NameCard *)a)->nameCardID - ((NameCard *)b)->nameCardID;
}
int main() {
NameCard nc[10];
nc[0] = (NameCard){1, "bill", "foo"};
nc[1] = (NameCard){3, "joe", "bar"};
nc[2] = (NameCard){2, "ben", "qux"};
show(nc, 3);
// calling the libraries' sort on the array; see "man qsort" for details
qsort(nc, 3, sizeof(NameCard), compareCardsById);
show(nc, 3);
return 0;
}
How can I complete the function canArrangeWords() ?
Question : Given a set of words check if we can arrange them in a list such that the last letter of any word and first letter of another word are same. The input function canArrangeWords shall contain an integer num and array of words arr. num denotes the number of word in the list (1<=num<=100). arr shall contain words consisting of lower case letters between 'a' - 'z' only . return 1 if words can be arranged in that fashion and -1 if cannot.
Input : 4 pot ten nice eye
output : 1
input : 3 fox owl pond
output: -1
Please help me complete this program .
**
#include<stdio.h>
#include<string.h>
int canArrangewords(int,char [100][100]);
void main(){
int n ,count=0 , i ;
char arrayS[100][100];
scanf("%d",&n);
for (i = 0; i < n; ++i)
{
scanf("%s",arrayS[i]);
}
for(i=0;i<n;i++)
{
printf("%s",arrayS[i]);
printf("\n");
}
printf("%c\n",arrayS[2][4]);
canArrangewords(n , arrayS);
}
int canArrangewords(int n,char arrayS[100][100]){
int i , j ;
for ( i = 0; i < n; i++)
{
for ( j = i+1 ; j < strlen(arrayS[j+1]); i++)
{
int flag = strlen(arrayS[j+1]) - 1;
int temp = strcmp(arrayS[i][0],arrayS[j][flag]);
}
}
}
}
Well, first of all think of the way you can reach that answer.
If you only need to know if they can or can not be arranged and you do not have to do so your self you can use an empty array of int array[26] for each letter a-z.
The rule is that from all the first and last letters for all the words only two MAY appear an odd amount of times - the first letter of first word in list and the last letter in the last word in the list, the rest MUST appear an even amount of times. I would add a check to make sure the letters are lowercase as well. good luck!
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MINASCII 97
#define LETTERS 26
void UpdateArray(char letter, int* arr)
{
if(arr[letter - MINASCII] == 0)
{
++arr[letter - MINASCII];
}
else
{
--arr[letter - MINASCII];/*for each second time same letter is seen reduce back to zero */
}
}
int canArrangewords(int wordNum, char* wordArr[])
{
int arr[LETTERS] = {0};
int i = 0;
int count = 0 ;
char first;
char last;
char* string;
for (i= 0; i< wordNum; ++i)
{
string = wordArr[i];
first = string[0];
last = string[strlen(string)-1];
UpdateArray(first, &arr[0]);
UpdateArray(last, &arr[0]);
}
for(i = 0; i< LETTERS; ++i)
{
count+=arr[i];
}
if(count == 2 || count == 0)/*either once each or twice -see word1 example in main*/
{
return 1;
}
return -1;
}
int main()
{
int i = 0;
char* words[] = {"pot", "ten", "nice", "eye"};
char* words1[] = {"pot", "ten", "nip"};
char* words2[] = {"fox", "owl", "pond"};
i = canArrangewords(4,words);
printf("%d\n", i);
i = canArrangewords(3,words1);
printf("%d\n", i);
i = canArrangewords(3,words2);
printf("%d\n", i);
return 0;
}
Change your array of words into an array of pointers to words. Then you can simply exchange the pointers.
To speed things up, instead of a pointer to a word, have it point to a structure:
struct WORD {
char *firstchar; // begin of word
char *lastchar; // last char of word
} *words[100]; // array of 100 pointers to words
To read the words:
char buf[100];
for (i = 0; i < n; ++i)
{
scanf("%s",buf);
int len= strlen(buf);
words[i]= malloc(sizeof(struct WORDS));
words[i]->firstchar= malloc(len+1);
strcpy(words[i]->firstchar, buf);
words[i]->lastchar= words[i]->firstchar + len-1;
}
Now compare and sort:
if (*words[i]->lastchar == *words[j]->firstchar) {
struct WORDS *tmp= words[i+1];
words[i+1]= words[j];
words[j]= tmp;
}
Do this in a loop, a kind of bubble sort. I leave that to you.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
This code take input from the user (characters C,T,B) and (int 0-24 and 0-60) to calculate the cost of parking based on the type of vehicle the user inputs.
the last line of code in the program is supossed to print the result of the function "charged" which is determined by the type of vehicle declared by the user inputed char value but when i run it only retruns 0.00 instead of the flaot value any and all help is appreciated :)
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int total_minute_parked (int minute_in, int minute_left)
{
int minute_parked;
if (minute_in > minute_left)
{
minute_parked = (minute_left - minute_in + 60);
}
else
{
minute_parked = (minute_left - minute_in);
}
return minute_parked;
}
// func calc total hours parked
int total_hour_parked (int hour_in, int hour_left)
{
int hours_parked;
if (hour_left > hour_in)
{
hours_parked = abs((hour_left - 1) - hour_in);
}
else
{
hours_parked = abs(hour_left - hour_in);
}
return hours_parked ;
}
// -------------------funtion to calc charge based off type of vehicle------
float charged (char vehicle_type,int total_hour_parked)
{
char C;
char T;
char B;
float temp_charged;
if (vehicle_type == C) // -------------------------------CAR
{
if (total_hour_parked > 3)
{
float secondary_hour = total_hour_parked - 3;
temp_charged = secondary_hour * 1.5;
}
else
{
temp_charged = 0;
}
}
else if (vehicle_type == T) // ------------------------------TRUCK
{
if (total_hour_parked > 2)
{
float secondary_hour = total_hour_parked - 2;
temp_charged = (secondary_hour * 2.3) + 1.0;
}
else {
temp_charged = 1;
}
}
else if (vehicle_type == B) // -----------------------------------BUS
{
if (total_hour_parked > 1)
{
float secondary_hour = total_hour_parked - 1;
temp_charged = (secondary_hour * 3.7) + 2.0;
}
else {
temp_charged = 2;
}
}
return temp_charged;
}
//---------------------- end program upon invalid imput -------------------//
// --------------------- main that prints results and takes imput -----------//
int main()
{
int total_hour_parked (int hour_in,int hour_left);
float charged (char vehicle_type, int total_hour_parked);
char vehicle_type;
int hour_in = 0;
int minute_in = 0;
int hour_left = 0;
int minute_left = 0;
printf("Please enter the type of Vehicle:");
scanf("%c",&vehicle_type);
printf("Please enter the hour entered lot:");
scanf("%d", &hour_in);
printf("Please enter the minute entered lot:");
scanf("%d", &minute_in);
printf("Please enter the hour left lot:");
scanf("%d", &hour_left);
printf("Please enter the minute left lot:");
scanf("%d", &minute_left);
printf("------------------------------------\n");
printf("Parking time: %d:%d\n", total_hour_parked(hour_in,hour_left),total_minute_parked(minute_in,minute_left));
printf("Cost %f",charged(vehicle_type,total_hour_parked));
return 0;
}
I'm not sure if it's going to solve all the problems in the code, but there's an issue here:
char C;
char T;
char B;
float temp_charged;
if (vehicle_type == C) // -------------------------------CAR
What this does is it declares three char and doesn't assign any value (so accessing them is undefined and will result in some rubbish value). Then you are comparing vehicle_type against those chars. The result will most likely be false (or 0). That's not what you intended. Instead, do this:
if (vehicle_type == 'C')
You probably misunderstood what char C; means. It doesn't mean "make a char with value 'C'", but "make a char named C and don't initialize it". But in this scenario you don't need those three chars anyway bcause you can just compare vehicle_type with a literal.
Their are several problems in the above code.
1). You are comparing vehicle_type with the char which are not assign so first assign the values to this char variables
char C = 'C';
char T = 'T';
char B = 'B';
Or you can directly compare like
if (vehicle_type == 'T')
2). total_hour_parked is a function not a integer variable so what you can do is store the return value of total_hour_parked in any variable
Eg:-
int m_total_hour_parked = total_hour_parked(hour_in, hour_left);
printf("Parking time: %d:%d\n", m_total_hour_parked, total_minute_parked(minute_in, minute_left));
printf("Cost %f", charged(vehicle_type, m_total_hour_parked));
Hopefully that helps
I recently joined Stackoverflow community because I had to ask this question. I've been searching for possible explanations and solutions on the website but so far nothing enlightened me as I wanted. My error is probably caused by a very specific line of code. I'm trying to create a function that reads an array of struct votes, (struct contains integer member number, char *category, char *nominee) and copies all the votes that contain the same number and category to another array of struct. Basically to show all the repeated votes.
typedef struct
{
int member;
char *categ;
char *nom;
}Vote
Vote vote(int member, char *categ, char *nom)
{
Vote result;
result.member = member;
result.categ = categ;
result.nom = nom;
return result;
}
int votes_count(Vote *v, int n, Vote *v1)
{
int result = 0;
int *index = malloc(sizeof(int) * 1000);
int a = 0;
for (int i = 0; i < n; ++i)
{
for (int j = 0; j < n; ++j)
{
if (a == 0 && v[i].member == v[j].member && strcmp(v[i].categ, v[j].categ) == 0)
{
v1[result++] = vote(v[j].member, str_dup(v[j].categ), str_dup(v[j].nom));
index[a++] = j;
}
for (int b = 0; b < a; ++b)
{
if( a > 0 && v[i].member == v[j].member && strcmp(v[i].categ, v[j].categ) == 0 && j != index[b])
{
v1[result++] = voto(v[j].member, str_dup(v[j].categ), str_dup(v[j].nom));
index[a++] = j;
}
}
}
}
return result;
}
Afterwads, it returns the number of elements of new array that contains all repetitions. I want to use an array of ints to save all line indexes so that the function doesn't read and copy the lines it already accounted.
Sorry if the code is hard to understand, if needed I can edit to be more understandable. Thanks for any answears.
P.S: I'm portuguese, sorry in advance for grammar mistakes
if your only intention is to harvest the duplicates, you only need to compare to the elements that came before an element
you don't need the index[] array
For simplicity, I used two integer arrays, you should change them to your struct arrays, also change the compare function.
unsigned fetchdups(int orig[], int dups[], unsigned count)
{
unsigned this, that, ndup=0;
for (this=1; this<count; this++){
for (that=0; that<this; that++){
/* change this to your compare() */
if(orig[that] == orig[this]) break;
}
if (this == that) continue; /* no duplicate */
dups[ndup++] = this;
}
return ndup;
}
I have a question regarding an issue with a program in C I am making. I am going to write two different strings next to each other in two columns. I haven't found clear answers to my question since they almost always give examples of numbers with a known length or amount.
I have two strings, with a maximum length of 1500 characters, but to me unknown length. Let's for the sake of learning given them these values:
char string1[] = "The independent country is not only self-governed nation with own authorities.";
char string2[] = "This status needs the international diplomatic recognition of sovereignty.";
I want to write them next to each other, with a column width of twenty characters. I have set the difference between the columns to a regular 'tab'. Like this:
The independent coun This status needs th
try is not only self e international dipl
-governed nation wit omatic recognition o
h own authorities. f sovereignty.
I have tried with the following code but it isn't effective since I can't figure out how to adapt it to the length of the strings. It also just adapted to write five rows. I also get the below error.
Could someone please give me an example of how this could be done, and maybe with a pre-defined c-function in order to avoid using the for-loops.
void display_columns(char *string1, char *string2);
int main()
{
char string1[] = "The independent country is not only self-governed nation with own authorities.";
char string2[] = "This status needs the international diplomatic recognition of sovereignty.";
display_columns(string1,string2);
}
void display_columns(char *string1, char *string2)
{
int i,j;
for(i=0;i<5;i++)
{
for(j=0+20*i;j<20+20*i;j++)
{
printf("%c",string1[j]);
}
printf("\t");
for(j=0+20*i;j<20+20*i;j++)
{
printf("%c",string2[j]);
}
}
}
I guess this is more generic way to do it.
void print_line(char *str, int *counter) {
for (int i = 0; i < 20; i++) {
if (str[*counter] != '\0') {
printf("%c", str[*counter]);
*counter += 1;
}
else { printf(" "); }
}
}
void display_columns(char *string1, char *string2)
{
int counter = 0, counter2 = 0;
while (1) {
print_line(string1, &counter);
printf("\t");
print_line(string2, &counter2);
printf("\n");
if (string1[counter] == '\0' && string2[counter2] == '\0') {
break;
}
}
}
To print a single character, use:
printf("%c",string1[j]);
or
putchar(string1[j]);
This is the reason for the warnings and segmentation fault.
With this fix, the program somewhat works, you just have to print a newline as the last part of the loop:
for(i=0;i<5;i++)
{
for(j=0+20*i;j<20+20*i;j++)
{
putchar(string1[j]);
}
printf("\t");
for(j=0+20*i;j<20+20*i;j++)
{
putchar(string2[j]);
}
putchar('\n');
}
Update: For the function to work with strings of variable lengths, try this:
void display_columns(char *string1, char *string2)
{
int i,j;
int len1 = strlen(string1);
int len2 = strlen(string2);
int maxlen = (len1 > len2) ? len1 : len2;
int numloops = (maxlen + 20 - 1) / 20;
for(i=0; i<numloops; i++)
{
for(j=0+20*i;j<20+20*i;j++)
{
if (j < len1)
putchar(string1[j]);
else
putchar(' '); // Fill with spaces for correct alignment
}
printf("\t");
for(j=0+20*i;j<20+20*i;j++)
{
if (j < len2)
putchar(string2[j]);
else
break; // Just exit from the loop for the right side
}
putchar('\n');
}
}