I'll make this short. I really want to learn from the answer. I am not here to make anyone code for me, so you choose if you want to learn me how to solve this problem or simply write the whole code.
I am trying to make a script which can read a CSV with this pattern:
DATE,TEXT,EXPENSE or INCOME,BALANCE,STATUS,DENIED.
Example: 11.01.2011,Grocery shop, -200, 700, Done, No.
I want the output to be the sum of all the expenses and income and second output what the balance is. I would like this info to be stored somewhere in the CSV file, so when I open it with excel it's there.
If you are able to explain what each line does it would be great for me so I can learn as a coding noob, but if not that's all good.
If this question is already answered I am so sorry. I have tried for a couple hours to find a answer, but I have only gotten some code that I don't know how to modify to what I want to do.
For any problem like this, I prefer to do it as a loop, structured in several parts:
read lines of text
when there are no more lines, we're done
for each line, break it into a number of fields
finally, do something interesting with the fields
The basic C function for step 1 is the fgets function. It's customery to bundle step 1 and step 2 together in the header of a while loop:
char linebuf[100];
while(fgets(linebuf, sizeof(linebuf), infp) != NULL) {
step 3; step 4;
}
Now, in the body of the loop, we have a line of text linebuf we've just read, and it's time to break it up into fields, in this case by searching for comma characters as delimiters. One way to do this sort of thing is using the library function strtok. Another is described in this chapter of some programming notes.
For files with columns of data, I like to store the broken-out fields in an array of pointers:
char *fields[MAXCOLS];
So then, you can use ordinary string operations to do interesting things with the columns (remembering that arrays in C are 0-based).
For example, to see if column 3 is the word "yes" or something else:
if(strcmp(fields[2], "yes") == 0) {
/* column 3 was "yes" */ ;
} else {
/* column 3 was something else */ ;
}
If column 5 was an amount, convert it to a number so you can do something with it:
double amount, running_total;
/* ... */
amount = atof(4);
running_total += amount;
(But beware: types float or double are not always good for dealing with monetary amounts, due to roundoff issues.)
I have to map consecutive integer codes from 1 to 100 to strings in C. Normally, for a mapping of number to string, I would have something like this:
#define code1 1
#define code2 2
.
.
#define code100 100
struct map
{
int code;
char *msg;
}objs[100];
I would then loop over the objs and if the number matches, I would use the corresponding string of the obj array. Since I know that the numbers to be mapped are consecutive, I can just do this:
const char *arr[100] = { "abc", "def", ....... "100th msg"};
I can then forget the looping and just print arr[code]. Is this a bad approach? The only disadvantage I see is that when somebody else adds a code in the middle, they have to be careful about it. The advantage is obviously that I don't need to loop over the struct array.
Using a direct indexed array is a commonly used approach that works fine if the data never (rarely) changes, and there are not too many gaps, because you spend a record for every gap. At some point the management or the storage cost of the gaps may become an issue.
If you need to cope with more dynamic compile-time updates to the data then the next best thing is a sorted array. If you can guarantee that your entries are always in order but perhaps there are gaps, or new entries added to the end, then you can binary chop your ordered array to quickly find the entry you want. You may want to do a start-up pass that checks the array is correctly ordered, but you only have to do that once.
If you need to worry about runtime updates, then you seriously need to consider higher-level container abstractions such as mapping trees or hashmaps.
Suppose the array has error messages. Then a common approach is to define constants fo each error and print the message associated with it, for example:
#define ERR_NONE 0
#define ERR_NOMEM 1
#define ERR_BADNUM 2
// etc
and define the array as:
const char *msgs[] = {
"No error",
"Out of memory",
"Bad number",
// etc
};
and have a function to print the message, for example:
void printmsg(int code)
{
printf("%s\n",msgs[code]);
}
which can be called as
printmsg(ERR_NOMEM);
For modularity, the #defines can be in e.g. errors.h, together with the prototype of printmsg, and the array can be in errors.c.
The only problem with your approach is that the codes can never change. You can't add intermediate codes without changing the entire code. But it should work. Also the first code should be zero or you'll have to either pad the array or shift the codes when accessing.
Essentially what you have is an immutable hash table.
#define BASE_CODE 5
#define CODE_BLUE 5
#define CODE_GREEN 6
const char *responses[] = {'blue', 'green'};
printf("%s\n", responses[code - BASE_CODE]);
If you want to be able to change the codes (add, remove, insert codes in the middle of the sequence, verify if a code was properly referenced), then you should stick with the first approach, but add a hash function so you don't need to loop sequentially over the array.
I am currently working on a C project that requires the creation, storage and mathematical usage of numbers that are too large to be put into normal variable types. To do this, we were instructed to represent numbers as a sequence of digits stored in an array of integers. I use a struct defined as so:
struct BigInt {
int val[300000];
int size;
};
(I know I can dynamically allocate memory, and that that is
preferable, however this is how I am most comfortable doing it, it has
worked perfectly fine so far and this is how the professor instructed us to do it.)
I then define member A:
struct BigInt A={NULL};
I can generate and store, then add, subtract and multiply random numbers with this, and they can have any number digits up to 300000(far more than I will ever need to account for). For example, if the number 1432 was generated and stored into BigInt A, A.size would be 4 and A.val[2] would be 3.
Now I need to create a way to store user input into this type. For example, the user needs to be able go straight from inputting 50! and then it be stored into this struct array type I have created. How would I go about doing this?
The only ways that I could think of would be to store the user input as a string then have the math in that string be executed multiple times, each time storing a different digit, or reading numbers straight off of stdout, but I don't know if either of those are even possible or would solve my problem.
You can try using string as follows:
char s[300001];
scanf("%s", s);
A.size = strlen(s);
for(int i = 0; i < A.size; i++){
A.val[i] = s[i] - '0';
}
I think it will solve your problem, but this way of implementation for big integers is not efficient though.
Sorry for previous answer, to solve in c you need to use array of chars to store each digits.
Hey everyone, I'm basically new to programming. I've decided to try and get started with C (not C++ or C#) and so far I've been doing pretty well. I managed to get far as two-dimensional arrays before I started to falter. While I think I broadly understand 2D integer arrays, I certainly don't understand 3D string arrays.
I'm learning by taking the techniques and applying them in an actual program I've created, an exchange rate "calculator" that basically takes asks the user to select a base currency then prints its value in USD. There's no maths involved, I simply googled stuff like EUR/USD and set the values manually in the array which I discuss below.
But here's where I'm getting stuck. I figure the best way to learn multi-dimensional arrays is to practically apply the theory, so here's what I've typed so far (I've omitted the other functions of my program (including the code which calls this function) for brevity):
char currencies[5][3][4] = {
{'1','2','3','4','5'},
{'GBP','EUR','JPY','CAD','AUD'},
{'1.5','1.23','0.11','0.96','0.87'}
};
int point, symbol, value;
displayarraycontents()
{
for(point=1;point<5;point++){
for(symbol=1;symbol<5;symbol++){
for(value=1;symbol<5;symbol++)
printf("%s ", currencies[point][symbol][value]);
printf("\n");
}}
}
Because C doesn't feature a string data type, building string arrays completely messes with my head.
Why currencies[5][3][4]? Because I'm storing a total of 5 currencies, each marked by a 3-letter symbol (eg EUR, CAD), which have a value of up to 4 digits, including the decimal point.
I'm trying to display this list:
1 GBP 1.5
2 EUR 1.23
3 JPY 0.11
4 CAD 0.96
5 AUD 0.87
When I click build, the line where I specify the values in the array is highlighted with several instances of this warning:
warning: overflow in implicit constant conversion
...and the line where I print the contents of the array is highlighted with this warning:
warning: format '%s' expects type 'char *', but argument 2 has type 'int'
Upon running the code, the rest of the program works fine except this function, which produces a "segmentation error" or somesuch.
Could somebody give me a hand here? Any help would be greatly appreciated, as well as any links to simple C 2D/3D string array initialisation tutorials! (my two books, the K&R and Teach Yourself C only provide vague examples that aren't relevant)
Thanks in advance!
-Ryan
EDIT: updated code using struct:
struct currency {
char symbol[4];
float value[5];
};
void displayarraycontents(){
int index;
struct currency currencies[] {
{"GBP", 1.50},
{"EUR", 1.23},
{"JPY", 0.11},
{"CAD", 0.96},
{"AUD", 0.87},};
}
I get the following errors:
main.c:99: error: nested functions are disabled, use -fnested-functions to re-enable
main.c:99: error: expected '=', ',', ';', 'asm' or 'attribute' before '{' token
main.c:100: error: expected ';' before '}' token
main.c:100: error: expected expression before ',' token
In the actual code window itself, every symbol is flagged as an "unexpected token".
In this case, you don't actually want a 3D array. In fact, since you have a table of values, all you need is a 1D array.
The tricky part is that each element of the array needs to store two things: the currency symbol, and the associated exchange rate. C has a way of building a type that stores two things - it's the struct mechanism. We can define a struct to hold a single currency:
struct currency {
char symbol[4];
char value[5];
};
(Note that this does not create a variable; it creates a type. struct currency is analagous to char, except that we defined the meaning of the former ourselves).
...and we can now create an array of 5 of these:
struct currency currencies[5] = {
{"GBP", "1.5" },
{"EUR", "1.23" },
{"JPY", "0.11" },
{"CAD", "0.96" },
{"AUD", "0.87" } };
To iterate over them and print them out, the code would look like:
void displayarraycontents(void)
{
int point;
for(point = 0; point < 5; point++)
{
printf("%d %s %s\n", point + 1, currencies[point].symbol, currencies[point].value);
}
}
You need a to correct your array dimensions, and you also need to declare your strings as strings, not as multibyte character constants:
char currencies[3][5][5] = {
{"1","2","3","4","5"},
{"GBP","EUR","JPY","CAD","AUD"},
{"1.5","1.23","0.11","0.96","0.87"}
};
Your logic for the array dimensions is wrong - what you want is 3 columns, each with 5 entries, each of which is a string 5 bytes long.
Your for loop should index from 0, not from 1.
There is also a oops in for statements:
for(point=1;point<5;point++)
First item in an array is in 0 position, so for statements should be like this:
for(point=0;point<5;point++)
It would make more sense to use structs here rather than a multi-dimensional array.
#include <stdio.h>
typedef struct Currency {
const char* symbol;
double value;
} Currency;
Currency CURRENCIES[] = {
{"GBP", 1.5},
{"EUR", 1.23},
{"JPY", 0.11},
{"CAD", 0.96},
{"AUD", 0.87},
};
size_t NUM_CURRENCIES = sizeof(CURRENCIES) / sizeof(Currency);
int main()
{
size_t index;
for (index = 0; index < NUM_CURRENCIES; index++)
{
printf("%zu %s %.2f\n",
index + 1, CURRENCIES[index].symbol, CURRENCIES[index].value);
}
return 0;
}
It should be
char currencies[3][5][5] = {
because it contains 3 lists containing 5 strings each.
Each string has a max of 4 characters, but you need the additional NUL character, so 5 at the end.
-- EDIT
You have the array access confused. Using your array definition (fixed as above) it would be currencies[data_type][index] to get a string.
data_type = 0 -> the index
data_type = 1 -> the symbol
data_type = 2 -> the value
the first line
{'1','2','3','4','5'},
is redundant.
Fixed code:
char currencies[2][5][5] = {
{"GBP","EUR","JPY","CAD","AUD"},
{"1.5","1.23","0.11","0.96","0.87"}
};
void displayarraycontents()
{
int index;
for(index = 0;index < 5;index++) {
printf("%i %s %s\n", index, currencies[0][index], currencies[1][index]);
}
}
In C/C++ you would normally read your array dimentions from right to left to get a good idea of how the compiler will see it. In this case, you need to store strings of 4 characters each which requires storage for 5 chars (to include the trailing \0) therefore [5] will be the array size. Next you are storing groups of 5 items, therefore the middle value will be [5] and finally, you are storing a total of 3 groups of these items, therefore [3]. The final result of all of this is char currencies[3][5][5] = . . .;
Of course, as replied elsewhere, you need to use the double quotes for string values.
If you want to solve this with multi-dimensional arrays, as #Forrest says, you need [3][5][5]. Look at it this way: in the initializer, find the outermost braces: inside that, on the top level, how many elements are there? 3. Now, each of these elements (one level in), how many elements? 5. Drilling further down, inside each of those, you have a string of 4 elements, plus one for the terminator, again 5.
Second error: you can only ever have one character in single quotes, like 'a'; that's char type, and equivalent to ASCII code (97 in this case). For strings, you have to use double quotes ("abc", which is equivalent to {97, 98, 99, 0}).
Third error: loops. You are not actually iterating over all three loops while printing a string at a time (since printf will actually do one of the loops for you) - so you should only have 2 loops (or, less efficiently, you can keep all three loops, but then print only a character at a time). Also, you need to be aware of the loop limits; you are going up to 5 in each case, but this will give you runtime garbage (in the best case) or runtime crash (in the worst case) when you go out of your [3] dimension. Thus, something like this:
Then again, your innermost loop is inconsistent in your variable usage (copy-paste error).
However, there will almost never be need to write code like this. You mainly use 2D arrays for matrix operations. Something like this should only have a one-dimensional array, storing record elements.
struct currency {
int id;
char[4] symbol;
float value;
} currencies[5];
You don't need to store the indices (1-5) as you can access the array (0-4) and thus know the indices. You can encapsulate the other values in a struct or two seperate arrays which gets your array(s) down to one dimension as it should be... In that way the items have proper types and you don't misuse two-dimensional arrays.
A 2D or 3D area shouldn't be filled with items that should be of a different type, it is needed when you have items that are of the same type and have a logic 2D or 3D structure. The pixels on your screen are a good example of something that needs a 2D structure, coordinates in a 3D graph are a good example of something that needs a 3D structure.