insert_event #1
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,2 +1,4 @@
|
||||
a.out
|
||||
ics_analyzer
|
||||
.gitconfig
|
||||
*.o
|
||||
|
12
README.md
12
README.md
@ -21,14 +21,17 @@ sudo make install
|
||||
|
||||
the default path is for evolution ics files at `~/.local/share/evolution/calendar/system/calendar.ics`
|
||||
```
|
||||
ics_analyzer
|
||||
icscli
|
||||
```
|
||||
|
||||
for a custom path
|
||||
```
|
||||
ics_analyzer -f path/to/ics/file.ics
|
||||
icscli -f path/to/ics/file.ics
|
||||
```
|
||||
|
||||
```
|
||||
icscli -h
|
||||
```
|
||||
|
||||
|
||||
#### uninstall
|
||||
@ -39,9 +42,6 @@ sudo make uninstall
|
||||
|
||||
#### TODO
|
||||
|
||||
- option to add events (evolution does not care about duplicate uuids)
|
||||
(but use libuuid to create uuids)
|
||||
- add option to print upcoming events only until a certain date
|
||||
- improve makefile
|
||||
- rename executable to ics_cli
|
||||
- show end date for events that span over multiple days
|
||||
- tests
|
||||
|
33
docs/ics_format.txt
Normal file
33
docs/ics_format.txt
Normal file
@ -0,0 +1,33 @@
|
||||
ICS files from Microsoft Outlook differ from those that were created by Gnome Evolution.
|
||||
(semicolons are used instead of colons at some position)
|
||||
|
||||
Evolution
|
||||
---------
|
||||
all line endings are \r\n
|
||||
|
||||
all day event:
|
||||
DTSTART;VALUE=DATE:20230908
|
||||
DTEND;VALUE=DATE:20230909
|
||||
|
||||
an all day event can span over multiple days and look like this:
|
||||
DTSTART;VALUE=DATE:20230911^M$
|
||||
DTEND;VALUE=DATE:20230916^M$
|
||||
|
||||
appointment:
|
||||
DTSTART;TZID=/freeassociation.sourceforge.net/Continent/City:
|
||||
20230909T090000
|
||||
DTEND;TZID=/freeassociation.sourceforge.net/Continent/City:
|
||||
20230909T093000
|
||||
|
||||
appointments can also span over multiple days:
|
||||
DTSTART;TZID=/freeassociation.sourceforge.net/Europe/Berlin:
|
||||
20230913T230000
|
||||
DTEND;TZID=/freeassociation.sourceforge.net/Europe/Berlin:
|
||||
20230914T040000
|
||||
|
||||
SEQUENCE is the number of times the event was modified.
|
||||
Evolution sets this to 2 after it has been generated.
|
||||
|
||||
Appointments include the continent and city of the used time zone.
|
||||
|
||||
"DESCRIPTION:" is an optional field.
|
32
makefile
32
makefile
@ -1,32 +0,0 @@
|
||||
all:
|
||||
gcc -Wall ./src/*.c
|
||||
|
||||
.PHONY: debug
|
||||
debug:
|
||||
gcc -Wall -g ./src/*.c
|
||||
gdb a.out
|
||||
|
||||
.PHONY: run
|
||||
run:
|
||||
gcc -Wall ./src/*.c
|
||||
./a.out
|
||||
|
||||
.PHONY: install
|
||||
install: a.out
|
||||
cp a.out /usr/local/bin/ics_analyzer
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
rm a.out
|
||||
|
||||
.PHONY: uninstall
|
||||
uninstall:
|
||||
rm /usr/local/bin/ics_analyzer
|
||||
|
||||
.PHONY: test
|
||||
test:
|
||||
./a.out
|
||||
@echo
|
||||
./a.out -h
|
||||
@echo
|
||||
./a.out -f tests/calendar.ics
|
45
src/Makefile
45
src/Makefile
@ -1,33 +1,42 @@
|
||||
.PHONY:all
|
||||
all:
|
||||
gcc -Wall *.c
|
||||
CC = gcc
|
||||
CFLAGS = -Wall
|
||||
LDFLAGS = -luuid
|
||||
|
||||
.PHONY:debug
|
||||
debug:
|
||||
gcc -Wall -g *.c
|
||||
gdb a.out
|
||||
# List of all source files (assuming they're all in the same directory)
|
||||
SRC_FILES = $(wildcard *.c)
|
||||
|
||||
.PHONY:run
|
||||
run:
|
||||
gcc -Wall *.c
|
||||
./a.out
|
||||
# Generate a list of object files by replacing the .c extension with .o
|
||||
OBJ_FILES = $(SRC_FILES:.c=.o)
|
||||
|
||||
EXECUTABLE = "icscli"
|
||||
|
||||
# linking
|
||||
$(EXECUTABLE): $(OBJ_FILES)
|
||||
gcc -Wall $(OBJ_FILES) -o $(EXECUTABLE) $(LDFLAGS)
|
||||
|
||||
main.o: main.c
|
||||
$(CC) $(CFLAGS) -c $<
|
||||
|
||||
# use implicit rule to compile C source files to object files
|
||||
%.o: %.c %.h
|
||||
$(CC) $(CFLAGS) -c $<
|
||||
|
||||
.PHONY:install
|
||||
install: a.out
|
||||
cp a.out /usr/local/bin/ics_analyzer
|
||||
install: $(EXECUTABLE)
|
||||
cp $(EXECUTABLE) /usr/local/bin/$(EXECUTABLE)
|
||||
|
||||
.PHONY:clean
|
||||
clean:
|
||||
-rm a.out
|
||||
-rm $(EXECUTABLE) *.o
|
||||
|
||||
.PHONY:uninstall
|
||||
uninstall:
|
||||
-rm /usr/local/bin/ics_analyzer
|
||||
-rm /usr/local/bin/$(EXECUTABLE)
|
||||
|
||||
.PHONY:test
|
||||
test:
|
||||
./a.out
|
||||
./$(EXECUTABLE)
|
||||
@echo
|
||||
./a.out -h
|
||||
./$(EXECUTABLE) -h
|
||||
@echo
|
||||
./a.out -f ../tests/calendar.ics
|
||||
./$(EXECUTABLE) -f ../tests/calendar.ics
|
||||
|
@ -1,3 +1,4 @@
|
||||
#include "insert_event.h"
|
||||
#include "cli_arg_parsing.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@ -5,37 +6,38 @@
|
||||
#include <string.h>
|
||||
|
||||
void usage() {
|
||||
printf ("-h\tprint this help\n");
|
||||
printf ("-f\tspecify ics file path\n");
|
||||
exit(0);
|
||||
printf ("-f [FILE PATH]\t\tspecify ics file path\n");
|
||||
printf ("-h\t\t\tprint this help\n");
|
||||
printf ("-i\t\t\tinsert an event\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
void get_cli_args(int argc, char **argv, char **file_name) {
|
||||
int opt = 0;
|
||||
int opt = 0;
|
||||
|
||||
memset(file_name, '\0', strlen(*file_name));
|
||||
memset(file_name, '\0', strlen(*file_name));
|
||||
|
||||
if (argc < 2) {
|
||||
char *home = getenv("HOME");
|
||||
*file_name = home;
|
||||
char *home = getenv("HOME");
|
||||
*file_name = home;
|
||||
|
||||
if (home != NULL) {
|
||||
strcat(*file_name, "/.local/share/evolution/calendar/system/calendar.ics");
|
||||
} else {
|
||||
printf ("Environment variable HOME is not set.\n");
|
||||
exit(1);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (home != NULL) {
|
||||
strcat(*file_name, "/.local/share/evolution/calendar/system/calendar.ics");
|
||||
} else {
|
||||
printf ("Environment variable HOME is not set.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
while ((opt = getopt(argc, argv, "f:h")) != -1) {
|
||||
switch(opt) {
|
||||
case 'f':
|
||||
*file_name = optarg;
|
||||
break;
|
||||
case 'h':
|
||||
usage();
|
||||
}
|
||||
}
|
||||
while ((opt = getopt(argc, argv, "f:hi")) != -1) {
|
||||
switch(opt) {
|
||||
case 'f':
|
||||
*file_name = optarg;
|
||||
break;
|
||||
case 'h':
|
||||
usage();
|
||||
break;
|
||||
case 'i':
|
||||
insert_event(*file_name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,41 +0,0 @@
|
||||
// cut a string into two parts by the first occurence of delimiter
|
||||
// and choose the first part (side 0) or the second part (side 1)
|
||||
// the chosen part will overwrite the original string
|
||||
|
||||
// cut a string into two parts by delimiter
|
||||
// and choose the first part (side 0) or the second part (side 1)
|
||||
// the chosen part will overwrite the original string
|
||||
|
||||
#include <string.h>
|
||||
|
||||
void cut_string(char my_string[], char delimiter, int side) {
|
||||
char part1[256] = "";
|
||||
char part2[256] = "";
|
||||
|
||||
int split = 0;
|
||||
|
||||
int j = 0;
|
||||
for (int i = 0; i < strlen(my_string); i++) {
|
||||
if (my_string[i] == delimiter) {
|
||||
if (split == 0) {
|
||||
split = 1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (split == 0) {
|
||||
part1[i] = my_string[i];
|
||||
} else {
|
||||
part2[j] = my_string[i];
|
||||
j++;
|
||||
}
|
||||
}
|
||||
|
||||
memset(my_string, '\0', strlen(my_string));
|
||||
if (side == 0) {
|
||||
strcpy(my_string, part1);
|
||||
} else {
|
||||
strcpy(my_string, part2);
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
// cut string into two parts and choose one part
|
||||
// side is 0 or 1
|
||||
void cut_string(char my_string[], char delimiter, int side);
|
@ -1,15 +1,23 @@
|
||||
#include "date_time_handling.h"
|
||||
#include "string_handling.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
// buffer needs to contain a string with a strlen of 15 (format: "xxxxxxxxTxxxxxx")
|
||||
// or a strlen of 16 (format: "YYYYmmddTHHMMSSZ")
|
||||
void get_date(char buffer[]) {
|
||||
// add 1 because strlen does not include the null character
|
||||
size_t buffer_size = strlen(buffer) + 1;
|
||||
time_t my_unix_ts = time(NULL);
|
||||
struct tm* my_tm_local = localtime(&my_unix_ts);
|
||||
strftime(buffer, buffer_size, "%Y%m%dT%H%M%S", my_tm_local);
|
||||
if (strlen(buffer) == 15) {
|
||||
strftime(buffer, buffer_size, "%Y%m%dT%H%M%S", my_tm_local);
|
||||
} else if (strlen(buffer) == 16) {
|
||||
strftime(buffer, buffer_size, "%Y%m%dT%H%M%SZ", my_tm_local);
|
||||
}
|
||||
}
|
||||
|
||||
// 20230823T194138 -> 2023-08-23 19:41:38
|
||||
@ -31,6 +39,26 @@ void pretty_print_date_time(char date_time[]) {
|
||||
}
|
||||
}
|
||||
|
||||
void marshall_date_time(char date_time[]) {
|
||||
char transformed_string[strlen(date_time)];
|
||||
int j = 0;
|
||||
remove_nl_and_cr(date_time);
|
||||
for (int i = 0; i<=strlen(date_time); i++) {
|
||||
if (date_time[i] != ':' && date_time[i] != '-') {
|
||||
if (date_time[i] == ' ') {
|
||||
transformed_string[j] = 'T';
|
||||
} else {
|
||||
transformed_string[j] = date_time[i];
|
||||
}
|
||||
|
||||
j++;
|
||||
}
|
||||
|
||||
}
|
||||
memset(date_time, '\0', strlen(date_time));
|
||||
strcpy(date_time, transformed_string);
|
||||
}
|
||||
|
||||
void print_end_date(char end_date[]) {
|
||||
// end_date is all day event
|
||||
if (strlen(end_date) == 8)
|
||||
@ -44,3 +72,17 @@ void print_end_date(char end_date[]) {
|
||||
printf ("%c%c", time[4], time[5]);
|
||||
}
|
||||
|
||||
char *get_tz() {
|
||||
char *timezone_path = malloc(256);
|
||||
ssize_t bytes_read = readlink("/etc/localtime", timezone_path, 255);
|
||||
|
||||
if (bytes_read != -1) {
|
||||
// Null-terminate the string
|
||||
timezone_path[bytes_read] = '\0';
|
||||
} else {
|
||||
perror("readlink");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return timezone_path;
|
||||
}
|
||||
|
@ -2,5 +2,7 @@
|
||||
#include <string.h>
|
||||
|
||||
void get_date(char buffer[]);
|
||||
char *get_tz();
|
||||
void pretty_print_date_time(char date_time[]);
|
||||
void marshall_date_time(char date_time[]);
|
||||
void print_end_date(char end_date[]);
|
||||
|
187
src/insert_event.c
Normal file
187
src/insert_event.c
Normal file
@ -0,0 +1,187 @@
|
||||
#include "insert_event.h"
|
||||
#include "string_handling.h"
|
||||
#include "date_time_handling.h"
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <uuid/uuid.h>
|
||||
|
||||
void insert_event(char *file_name) {
|
||||
int myfd = open(file_name, O_RDWR);
|
||||
int all_day_event = 0;
|
||||
char summary_buf[256] = "SUMMARY:";
|
||||
char *input_buffer = &summary_buf[8];
|
||||
uuid_t uuid;
|
||||
char uuid_str[37] = "";
|
||||
char dtstamp[] = "YYYYmmddTHHMMSSZ";
|
||||
char *time_zone = get_tz();
|
||||
char *dtstart_buffer = malloc(128);
|
||||
char *dtend_buffer = malloc(128);
|
||||
|
||||
remove_until_delim(time_zone, '/', 4);
|
||||
|
||||
printf("Insert a new event\n");
|
||||
|
||||
printf("Is this an all day event? [y/n] ");
|
||||
all_day_event = binary_user_choice();
|
||||
|
||||
printf("SUMMARY: ");
|
||||
fgets (input_buffer, (sizeof(summary_buf)-strlen(summary_buf)), stdin);
|
||||
|
||||
if (strchr(input_buffer, '\n') == NULL)
|
||||
printf ("The input has been truncated to:\n%s\n", input_buffer);
|
||||
|
||||
// modify the string to have \r\n line ending
|
||||
summary_buf[strlen(summary_buf)+1] = '\0';
|
||||
summary_buf[strlen(summary_buf)-1] = '\r';
|
||||
summary_buf[strlen(summary_buf)] = '\n';
|
||||
|
||||
uuid_generate(uuid);
|
||||
// parse uuid to a string
|
||||
uuid_unparse(uuid, uuid_str);
|
||||
|
||||
get_date(dtstamp);
|
||||
|
||||
get_dtstart_dtend(dtstart_buffer, all_day_event, "start");
|
||||
marshall_date_time(dtstart_buffer);
|
||||
form_dtstart_string(dtstart_buffer, time_zone);
|
||||
|
||||
get_dtstart_dtend(dtend_buffer, all_day_event, "end");
|
||||
marshall_date_time(dtend_buffer);
|
||||
form_dtend_string(dtend_buffer, time_zone);
|
||||
|
||||
seek_cal_end(myfd);
|
||||
write(myfd, "BEGIN:VEVENT\r\n", strlen("BEGIN:VEVENT\r\n"));
|
||||
write(myfd, "UID:", strlen("UID:"));
|
||||
write(myfd, uuid_str, strlen(uuid_str));
|
||||
write(myfd, "\r\n", strlen("\r\n"));
|
||||
write(myfd, "DTSTAMP:", strlen("DTSTAMP:"));
|
||||
write(myfd, dtstamp, strlen(dtstamp));
|
||||
write(myfd, "\r\n", strlen("\r\n"));
|
||||
write(myfd, dtstart_buffer, strlen(dtstart_buffer));
|
||||
write(myfd, dtend_buffer, strlen(dtend_buffer));
|
||||
write(myfd, "SEQUENCE:2\r\n", strlen("SEQUENCE:2\r\n"));
|
||||
write(myfd, summary_buf, strlen(summary_buf));
|
||||
write(myfd, "TRANSP:OPAQUE\r\n", strlen("TRANSP:OPAQUE\r\n"));
|
||||
write(myfd, "CLASS:PUBLIC\r\n", strlen("CLASS:PUBLIC\r\n"));
|
||||
write(myfd, "CREATED:", strlen("CREATED:"));
|
||||
write(myfd, dtstamp, strlen(dtstamp));
|
||||
write(myfd, "\r\n", strlen("\r\n"));
|
||||
write(myfd, "LAST-MODIFIED:", strlen("LAST-MODIFIED:"));
|
||||
write(myfd, dtstamp, strlen(dtstamp));
|
||||
write(myfd, "\r\n", strlen("\r\n"));
|
||||
write(myfd, "END:VEVENT\r\n", strlen("END:VEVENT\r\n"));
|
||||
|
||||
write(myfd, "END:VCALENDAR\r\n", strlen("END:VCALENDAR\r\n"));
|
||||
|
||||
close(myfd);
|
||||
free(time_zone);
|
||||
free(dtstart_buffer);
|
||||
free(dtend_buffer);
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
||||
void seek_cal_end(int fd) {
|
||||
char search_string[] = "END:VCALENDAR";
|
||||
int j = 0;
|
||||
char char_reader = '\0';
|
||||
|
||||
lseek(fd, -1, SEEK_END);
|
||||
|
||||
while(read(fd, &char_reader, 1)) {
|
||||
// no need to compare to the null terminator of the search_string
|
||||
if (char_reader == search_string[strlen(search_string)-j-1]) {
|
||||
j++;
|
||||
} else {
|
||||
j = 0;
|
||||
}
|
||||
if (j == (strlen(search_string))) {
|
||||
lseek(fd, -1, SEEK_CUR);
|
||||
break;
|
||||
}
|
||||
lseek(fd, -2, SEEK_CUR);
|
||||
}
|
||||
}
|
||||
|
||||
int binary_user_choice() {
|
||||
char input_buffer[64] = "";
|
||||
if (fgets (input_buffer, sizeof(input_buffer), stdin) == NULL) {
|
||||
printf ("an fgets error occured\n");
|
||||
}
|
||||
if (! strchr(input_buffer, '\n')) {
|
||||
printf ("Input buffer overflow!\n");
|
||||
exit(1);
|
||||
}
|
||||
if (input_buffer[0] == 'n' || input_buffer[0] == 'N') {
|
||||
return 0;
|
||||
} else if (input_buffer[0] == 'y' || input_buffer[0] == 'Y') {
|
||||
return 1;
|
||||
} else {
|
||||
printf ("Please enter a N/n or Y/y character!\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
// char *start_or_end should contain "start" or "end"
|
||||
void get_dtstart_dtend(char input_buffer[], int all_day_event, char *start_or_end) {
|
||||
if (all_day_event) {
|
||||
printf("Enter the %s date in YYYY-mm-dd format!\n", start_or_end);
|
||||
if (fgets(input_buffer, 128, stdin) == NULL) {
|
||||
perror ("fgets");
|
||||
exit(1);
|
||||
}
|
||||
if (strlen(input_buffer) != 11) {
|
||||
printf ("Wrong format!\n");
|
||||
exit(1);
|
||||
}
|
||||
} else {
|
||||
printf("Enter the %s date in YYYY-mm-dd HH:MM:SS format!\n", start_or_end);
|
||||
if (fgets(input_buffer, 128, stdin) == NULL) {
|
||||
perror ("fgets");
|
||||
exit(1);
|
||||
}
|
||||
if (strlen(input_buffer) != 20) {
|
||||
printf ("Wrong format!\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void form_dtstart_string(char dtstart_buffer[], char time_zone[]) {
|
||||
char dtstart_copy[strlen(dtstart_buffer)];
|
||||
strcpy(dtstart_copy, dtstart_buffer);
|
||||
|
||||
// not all day event
|
||||
if (strlen(dtstart_buffer) == 15) {
|
||||
strcpy(dtstart_buffer, "DTSTART;TZID=/freeassociation.sourceforge.net");
|
||||
strcat(dtstart_buffer, time_zone);
|
||||
strcat(dtstart_buffer, ":\r\n ");
|
||||
strcat(dtstart_buffer, dtstart_copy);
|
||||
} else {
|
||||
// all day event
|
||||
strcpy(dtstart_buffer, "DTSTART;VALUE=DATE:");
|
||||
strcat(dtstart_buffer, dtstart_copy);
|
||||
}
|
||||
strcat(dtstart_buffer, "\r\n");
|
||||
}
|
||||
|
||||
void form_dtend_string(char dtend_buffer[], char time_zone[]) {
|
||||
char dtend_copy[strlen(dtend_buffer)];
|
||||
strcpy(dtend_copy, dtend_buffer);
|
||||
|
||||
// not all day event
|
||||
if (strlen(dtend_buffer) == 15) {
|
||||
strcpy(dtend_buffer, "DTEND;TZID=/freeassociation.sourceforge.net");
|
||||
strcat(dtend_buffer, time_zone);
|
||||
strcat(dtend_buffer, ":\r\n ");
|
||||
strcat(dtend_buffer, dtend_copy);
|
||||
} else {
|
||||
// all day event
|
||||
strcpy(dtend_buffer, "DTEND;VALUE=DATE:");
|
||||
strcat(dtend_buffer, dtend_copy);
|
||||
}
|
||||
strcat(dtend_buffer, "\r\n");
|
||||
}
|
8
src/insert_event.h
Normal file
8
src/insert_event.h
Normal file
@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
void insert_event(char *file_name);
|
||||
void seek_cal_end(int fd);
|
||||
int binary_user_choice();
|
||||
void get_dtstart_dtend(char input_buffer[], int all_day_event, char *start_or_end);
|
||||
void form_dtstart_string(char dtstart_buffer[], char time_zone[]);
|
||||
void form_dtend_string(char dtend_buffer[], char time_zone[]);
|
@ -1,12 +1,11 @@
|
||||
#include "cli_arg_parsing.h"
|
||||
#include "date_time_handling.h"
|
||||
#include "list_handling.h"
|
||||
#include "cut_string.h"
|
||||
#include "string_handling.h"
|
||||
#include "move_lines.h"
|
||||
#include "read_until_nl.h"
|
||||
#include "read_until_string.h"
|
||||
#include "seek_string_a.h"
|
||||
#include "remove_whitespace.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
@ -14,8 +13,8 @@
|
||||
#include <limits.h>
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
char *ics_path = "";
|
||||
get_cli_args(argc, argv, &ics_path);
|
||||
char *ics_path = "";
|
||||
get_cli_args(argc, argv, &ics_path);
|
||||
|
||||
char my_line[4096] = "";
|
||||
|
||||
|
@ -1,45 +0,0 @@
|
||||
// this function removes all new lines and carriage returns from a string
|
||||
// you might want to write a new function that replaces '\r' and '\n'
|
||||
// with a delimiter of user's choice
|
||||
|
||||
#include <string.h>
|
||||
|
||||
void remove_nl_and_cr(char raw_string[]) {
|
||||
char processed_string[strlen(raw_string)];
|
||||
|
||||
// counter for num of elements of processed_string
|
||||
int j = 0;
|
||||
for (int i = 0; i<strlen(raw_string); i++) {
|
||||
if (raw_string[i] == '\n' || raw_string[i] == '\r') {
|
||||
continue;
|
||||
} else {
|
||||
processed_string[j] = raw_string[i];
|
||||
j++;
|
||||
}
|
||||
}
|
||||
processed_string[j] = '\0';
|
||||
|
||||
memset(raw_string, '\0', strlen(raw_string));
|
||||
strcpy(raw_string, processed_string);
|
||||
}
|
||||
|
||||
// remove new lines, carriage returns and spaces
|
||||
void remove_whitespace(char raw_string[]) {
|
||||
char processed_string[strlen(raw_string)];
|
||||
|
||||
// counter for num of elements of processed_string
|
||||
int j = 0;
|
||||
for (int i = 0; i<strlen(raw_string); i++) {
|
||||
if (raw_string[i] == '\n' || raw_string[i] == '\r' \
|
||||
|| raw_string[i] == ' ') {
|
||||
continue;
|
||||
} else {
|
||||
processed_string[j] = raw_string[i];
|
||||
j++;
|
||||
}
|
||||
}
|
||||
processed_string[j] = '\0';
|
||||
|
||||
memset(raw_string, '\0', strlen(raw_string));
|
||||
strcpy(raw_string, processed_string);
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
// this function removes all new lines and carriage returns from a string
|
||||
// you might want to write a new function that replaces '\r' and '\n'
|
||||
// with a delimiter of user's choice
|
||||
|
||||
#pragma once
|
||||
|
||||
void remove_nl_and_cr(char raw_string[]);
|
||||
void remove_whitespace(char raw_string[]);
|
103
src/string_handling.c
Normal file
103
src/string_handling.c
Normal file
@ -0,0 +1,103 @@
|
||||
// cut a string into two parts by the first occurence of delimiter
|
||||
// and choose the first part (side 0) or the second part (side 1)
|
||||
// the chosen part will overwrite the original string
|
||||
|
||||
// cut a string into two parts by delimiter
|
||||
// and choose the first part (side 0) or the second part (side 1)
|
||||
// the chosen part will overwrite the original string
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
void cut_string(char my_string[], char delimiter, int side) {
|
||||
char part1[256] = "";
|
||||
char part2[256] = "";
|
||||
|
||||
int split = 0;
|
||||
|
||||
int j = 0;
|
||||
for (int i = 0; i < strlen(my_string); i++) {
|
||||
if (my_string[i] == delimiter) {
|
||||
if (split == 0) {
|
||||
split = 1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (split == 0) {
|
||||
part1[i] = my_string[i];
|
||||
} else {
|
||||
part2[j] = my_string[i];
|
||||
j++;
|
||||
}
|
||||
}
|
||||
|
||||
memset(my_string, '\0', strlen(my_string));
|
||||
if (side == 0) {
|
||||
strcpy(my_string, part1);
|
||||
} else {
|
||||
strcpy(my_string, part2);
|
||||
}
|
||||
}
|
||||
|
||||
// this function removes all new lines and carriage returns from a string
|
||||
// you might want to write a new function that replaces '\r' and '\n'
|
||||
// with a delimiter of user's choice
|
||||
void remove_nl_and_cr(char raw_string[]) {
|
||||
char processed_string[strlen(raw_string)];
|
||||
|
||||
// counter for num of elements of processed_string
|
||||
int j = 0;
|
||||
for (int i = 0; i<strlen(raw_string); i++) {
|
||||
if (raw_string[i] == '\n' || raw_string[i] == '\r') {
|
||||
continue;
|
||||
} else {
|
||||
processed_string[j] = raw_string[i];
|
||||
j++;
|
||||
}
|
||||
}
|
||||
processed_string[j] = '\0';
|
||||
|
||||
memset(raw_string, '\0', strlen(raw_string));
|
||||
strcpy(raw_string, processed_string);
|
||||
}
|
||||
|
||||
// remove new lines, carriage returns and spaces
|
||||
void remove_whitespace(char raw_string[]) {
|
||||
char processed_string[strlen(raw_string)];
|
||||
|
||||
// counter for num of elements of processed_string
|
||||
int j = 0;
|
||||
for (int i = 0; i<strlen(raw_string); i++) {
|
||||
if (raw_string[i] == '\n' || raw_string[i] == '\r' \
|
||||
|| raw_string[i] == ' ') {
|
||||
continue;
|
||||
} else {
|
||||
processed_string[j] = raw_string[i];
|
||||
j++;
|
||||
}
|
||||
}
|
||||
processed_string[j] = '\0';
|
||||
|
||||
memset(raw_string, '\0', strlen(raw_string));
|
||||
strcpy(raw_string, processed_string);
|
||||
}
|
||||
|
||||
void remove_until_delim(char raw_string[], char delimiter, int occurence) {
|
||||
int chunk = 0;
|
||||
int j = 0;
|
||||
char *tmp_string = malloc(strlen(raw_string));
|
||||
memset(tmp_string, '\0', strlen(raw_string));
|
||||
|
||||
for (int i = 0; i < strlen(raw_string); i++) {
|
||||
if (raw_string[i] == delimiter) {
|
||||
chunk++;
|
||||
}
|
||||
if (chunk >= occurence) {
|
||||
tmp_string[j] = raw_string[i];
|
||||
j++;
|
||||
}
|
||||
}
|
||||
strcpy(raw_string, tmp_string);
|
||||
free(tmp_string);
|
||||
}
|
8
src/string_handling.h
Normal file
8
src/string_handling.h
Normal file
@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
// cut string into two parts and choose one part
|
||||
// side is 0 or 1
|
||||
void cut_string(char my_string[], char delimiter, int side);
|
||||
void remove_nl_and_cr(char raw_string[]);
|
||||
void remove_whitespace(char raw_string[]);
|
||||
void remove_until_delim(char raw_string[], char delimiter, int occurence);
|
Loading…
Reference in New Issue
Block a user