Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- VCF <-> CSV <-> VCF
- Everybody loves a neat contact list.
- But as time passes and you meet more people at school, college, parties and offices the contact list grows longer and more chaotic and less manageable.
- In earlier non-android phones transfering contact list was not an option but the contacts in my contact list were too dear to be just forgotten. I used to copy all the contacts I could (around 200-250 at a time) to the sim card, and then insert the sim in another phone and copy all from sim to phone. Repeat this 2-3 times and it was done. You can use this method to transfer your contacts from the old phone you have to an android phone.
- Once your contacts are in an android phone it is a lot more eaiser, to transfer your contact list from one phone to another, thanks to vcf file format.
- Although vcfs are easy to transfer and merge and share, as a vcf file becomes larger it becomes more redundant and chaotic. As we combine contacts from different phones and merge different vcf's, the contact list becomes more and more redundant. Sometimes a contact number appears multiple times under the same name, sometimes the same number is saved under different names on two different phones and when your merge you have two copies.
- The code here can list all the repeating contacts.
- Well, one problem down. But finding and deleting one contact a time in vcf is still neither easy nor feasible.
- It is impossible to handle and edit all the data of a vcf without getting a headache and two burning eyes.
- Would not it be better if you could convert your vcf file to a format which is gentle on eyes and easy to understand and edit? This is where csv files come it. csv files can be opened in spreadsheet (MS Excel etc) which means you can see ALL your contacts in a tabular format.
- Once you have your contact list in a tabular form you can edit it any way you want. You can delete a cards with just one tap of delete button. Edit a name simply by clicking on it instead of going through all the trouble that you do through android. You can sort the list by name and merge the see if their are multiple vcards of the same person, and then merge them in one vcard, all this as easily as simple Ctrl+c and Ctrl+v.
- You can do that with this program, and after you are done deleting redundant and outdated contacts and making your contact list better you can convert it back to vcf format and Import it to your android phonr and voila!!.. Your contact list is brand new.
- :)
- ---*/
- /*-----------------
- * AuthorName: Sayyad Shaha Hassan
- * Date: 23 August 2015
- *
- * This module converts vcf files to csv file.
- * A csv file can be opened in a spreadsheet for easy access and editing.
- *
- * The supported version is 2.1
- * Supported fields for each card are...
- * Name: Prefix, First, Mid, Last, Suffix
- * three Telephone numbers
- * two email IDs
- * Company, Title
- * Note
- * (one more extra field, other than the ones mentioned above)
- *
- * The fields other than the ones mentioned above will be added to NOTE section.
- * Only ascii names are supported.
- * commas used in NOTE will be replaced with period.
- * Do not use commas in Names please.
- */
- #include<stdio.h>
- #include<string.h>
- #define MAX_NAME 60
- #define MAX_FON 20
- #define MAX_XTRA 200
- FILE *gfpIn, *gfpOut;
- typedef struct
- {
- char szLastName[MAX_NAME];
- char szFirstName[MAX_NAME];
- char szMidName[MAX_NAME];
- char szPreName[MAX_NAME];
- char szSufName[MAX_NAME];
- char szFullName[MAX_NAME*4];
- char szTelCell[MAX_FON];
- char szTelHome[MAX_FON];
- char szTelX[MAX_FON];
- char szEmailHome[MAX_NAME];
- char szEmailX[MAX_NAME];
- char szOrg[MAX_NAME];
- char szTitle[MAX_NAME];
- char szNote[MAX_XTRA];
- char szExtra[MAX_XTRA];
- } Card;
- int Menu (int *choice);
- //displays menu and recieves a choice.
- int GetFileNames();
- //Gets filenames and returns handles.
- int VcfToCsv();
- //vcf file to csv
- int FindRepeat();
- //lists repeating numbers, uses CompareNumbers
- int CsvToVcf();
- //converts csv to vcf
- int FormatNumber (char szNum[MAX_FON]);
- //formats numbers as groups of 4 digits, right to left. eg ..x xxxx xxxx
- int CompareNumbers (char* Num1, char* Num2);
- //checks if lower 10 digits are the same (to ignore the std codes)
- int
- main(
- int argc,
- char *argv[]
- )
- {
- int ch;
- do
- {
- Menu(&ch);
- switch (ch)
- {
- // vcf -> csv
- case 1:
- if (GetFileNames ())
- {
- continue;
- }
- if (VcfToCsv() < 0)
- {
- printf("err in vcf2csf() ");
- return -2;
- }
- fclose( gfpIn);
- fclose( gfpOut);
- printf("\n Done....");
- break;
- //csv -> vcf
- case 2:
- if (GetFileNames ())
- {
- continue;
- }
- if (CsvToVcf())
- {
- printf("err in csfTovcf() ");
- return -2;
- }
- fclose( gfpIn);
- fclose( gfpOut);
- printf("\n Done....");
- break;
- case 3:
- FindRepeat();
- break;
- case 5:
- printf("\n Exiting...");
- break;
- default:
- printf("\n Invalid choice.");
- break;
- }
- }while (ch!= 4);
- return 0;
- }
- int
- CsvToVcf(
- )
- {
- int i, flag, fillFlag;
- Card card;
- for(i = 0; !feof(gfpIn); i++)
- {
- flag = fillFlag = 0;
- memset( &card, 0, sizeof(card));
- //read a line
- fillFlag += fscanf( gfpIn, "\n%[^,]s,", card.szLastName);
- fillFlag += fscanf( gfpIn, ",%[^,]s,", card.szFirstName);
- fillFlag += fscanf( gfpIn, ",%[^,]s,", card.szMidName);
- fillFlag += fscanf( gfpIn, ",%[^,]s,", card.szPreName);
- fillFlag += fscanf( gfpIn, ",%[^,]s,", card.szSufName);
- fillFlag += fscanf( gfpIn, ",%[^,]s,", card.szFullName);
- if (card.szPreName[0] != '\0')
- {
- sprintf(card.szFullName, "%s", card.szPreName);
- flag++;
- }
- if (card.szFirstName[0] != '\0')
- {
- if(flag > 0)
- {
- sprintf(card.szFullName, "%s %s", card.szFullName, card.szFirstName);
- flag++;
- }
- else //firstName is first trm
- {
- sprintf(card.szFullName, "%s%s", card.szFullName, card.szFirstName);
- flag++;
- }
- }
- if (card.szMidName[0] != '\0')
- {
- if(flag > 0)
- {
- sprintf(card.szFullName, "%s %s", card.szFullName, card.szMidName);
- flag++;
- }
- else
- {
- sprintf(card.szFullName, "%s%s", card.szFullName, card.szMidName);
- flag++;
- }
- }
- if (card.szLastName[0] != '\0')
- {
- if (flag > 0)
- {
- sprintf(card.szFullName, "%s %s", card.szFullName, card.szLastName);
- flag++;
- }
- else
- {
- sprintf(card.szFullName, "%s%s", card.szFullName, card.szLastName);
- flag++;
- }
- }
- if (card.szSufName[0] != '\0')
- {
- if (flag > 0)
- {
- sprintf(card.szFullName, "%s, %s", card.szFullName, card.szSufName);
- flag++;
- }
- else
- {
- sprintf(card.szFullName, "%s,%s", card.szFullName, card.szSufName);
- flag++;
- }
- }
- fillFlag += fscanf( gfpIn, ",%[^,]s,", card.szTelCell);
- fillFlag += fscanf( gfpIn, ",%[^,]s,", card.szTelHome);
- fillFlag += fscanf( gfpIn, ",%[^,]s,", card.szTelX);
- fillFlag += fscanf( gfpIn, ",%[^,]s,", card.szEmailHome);
- fillFlag += fscanf( gfpIn, ",%[^,]s,", card.szEmailX);
- fillFlag += fscanf( gfpIn, ",%[^,]s,", card.szOrg);
- fillFlag += fscanf( gfpIn, ",%[^,]s,", card.szTitle);
- fillFlag += fscanf( gfpIn, ",%[^,]s,", card.szNote);
- fillFlag += fscanf( gfpIn, ",%[^\n]s\n", card.szExtra);
- if (strcmp(card.szFirstName, "00FirstName") == 0)
- {
- i--;
- continue;
- }
- //write the card
- if (fillFlag > 0 )
- {
- fprintf( gfpOut, "BEGIN:VCARD\nVERSION:2.1\n");
- fprintf( gfpOut, "N:%s;%s;%s;%s;%s\n", card.szLastName, card.szFirstName, card.szMidName, card.szPreName, card.szSufName);
- fprintf( gfpOut, "FN:%s\n", card.szFullName);
- if (card.szTelCell[0] != '\0')
- {
- FormatNumber (card.szTelCell);
- fprintf( gfpOut, "TEL;CELL:%s\n", card.szTelCell);
- }
- if (card.szTelHome[0] != '\0')
- {
- FormatNumber (card.szTelHome);
- fprintf( gfpOut, "TEL;HOME:%s\n", card.szTelHome);
- }
- if (card.szTelX[0] != '\0')
- {
- FormatNumber (card.szTelX);
- fprintf( gfpOut, "TEL:%s\n", card.szTelX);
- }
- if (card.szEmailHome[0] != '\0')
- {
- fprintf( gfpOut, "EMAIL;HOME:%s\n", card.szEmailHome);
- }
- if (card.szEmailX[0] != '\0')
- {
- fprintf( gfpOut, "EMAIL:%s\n", card.szEmailX);
- }
- if (card.szOrg[0] != '\0')
- {
- fprintf( gfpOut, "ORG:%s\n", card.szOrg);
- }
- if (card.szTitle[0] != '\0')
- {
- fprintf( gfpOut, "TITLE:%s\n", card.szTitle);
- }
- if (card.szNote[0] != '\0')
- {
- fprintf( gfpOut, "NOTE:%s\n", card.szNote);
- }
- if (card.szExtra[0] != '\0')
- {
- fprintf( gfpOut, "%s\n", card.szExtra);
- }
- fprintf( gfpOut, "END:VCARD\n");
- }
- }
- printf("\n%d Contacts.", i-1);
- return 0;
- }
- int
- FormatNumber (
- char szNum[MAX_FON]
- )
- {
- int i, j, len;
- char szTemp[MAX_FON];
- //removing spaces
- for ( j = i = 0; szNum[i] != '\0'; i++)
- {
- if ( (szNum[i] == '+') || ((szNum[i] <= '9') && (szNum[i] >= '0')))
- {
- szTemp[j++] = szNum[i];
- }
- }
- szTemp[j] = '\0';
- len = strlen(szTemp);
- //copying szTemp to szNum. format ...xx xxxx xxxx
- i = j%4;
- strncpy(szNum, szTemp, i);
- j = i;
- while ( len > j)
- {
- szNum[i++] = ' ';
- strncpy(szNum+i, szTemp+j, 4);
- i += 4;
- j += 4;
- }
- szNum[i] = '\0';
- return 0;
- }
- int
- CompareNumbers(
- char* Num1,
- char* Num2
- )
- {
- char rev1[MAX_FON], rev2[MAX_FON];
- strcpy (rev1, Num1);
- strcpy (rev2, Num2);
- strrev(rev1);
- strrev(rev2);
- if (strncmp (rev1, rev2, 12) == 0)
- {
- return 0;
- }
- return -1;
- }
- int
- AppendAsNote(
- Card* card,
- char* szToAdd
- )
- {
- printf("\nThe \"%s\" of \"%s %s\" could not be saved, but added to Notes. Please save it manually\n", szToAdd, card->szFirstName, card->szLastName);
- sprintf (card->szNote, "%s. %s", card->szNote, szToAdd);
- return 0;
- }
- int
- VcfToCsv(
- )
- {
- unsigned int j, i;
- Card card;
- char szHead[50], szTemp[100];
- int FilledFlags;
- /*
- bit(1,2,3):1,2,4 if set => Cell, Home, and X phone filled, respectively & individually.
- bit(4,5):8,16 => EmailHome, emailX filled
- bit(6):32 => Extra field filled
- bit(8):128 => break outer loop
- */
- //dummy entry/Header.
- fprintf( gfpOut, "00LastName,00FirstName,00MidName,Prefix,Suffix,");
- fprintf( gfpOut, "FullName,");
- fprintf( gfpOut, "+ 9190 1234 5678,+9191 1234 1234,55 1123,");
- fprintf( gfpOut, "email@home.in,email@other.in,Org,Title,Note");
- fprintf( gfpOut, ",Extra\n");
- for(j = 0; !feof(gfpIn); j++) //1 card
- {
- memset (&card, '\0', sizeof(card));
- FilledFlags = 0;
- while (1) //read a card
- {
- //read header
- if ( 0 >= fscanf (gfpIn, "\n%[^:]s", szHead))
- {
- FilledFlags = (FilledFlags | 128);
- break;
- }
- //Note
- if( strncmp(szHead, "NOTE", 4) == 0)
- {
- fscanf(gfpIn, ":%[^\n]s\n", card.szNote);
- for (i=0; card.szNote[i] != '\0'; i++)
- {
- if( card.szNote[i] == ',')
- {
- card.szNote[i] = '.';
- }
- }
- }
- else //name
- if( strncmp( szHead, "N", 1) == 0)
- {
- fscanf (gfpIn, ":%[^;]s", card.szLastName);
- fscanf (gfpIn, ";%[^;]s", card.szFirstName);
- fscanf (gfpIn, ";%[^;]s", card.szMidName);
- fscanf (gfpIn, ";%[^;]s", card.szPreName);
- fscanf (gfpIn, ";%[^\n]s", card.szSufName);
- }
- else //Telephones
- if( strncmp (szHead, "TEL;CELL", 8) == 0)
- {
- if ((FilledFlags&01) == 0) //no overwrite Logic
- {
- fscanf (gfpIn, ":%[^\n]s", card.szTelCell );
- FormatNumber (card.szTelCell);
- FilledFlags = (FilledFlags | 01);
- }
- else if ((FilledFlags&04)==0)
- {
- fscanf (gfpIn, ":%[^\n]s", card.szTelX );
- FormatNumber (card.szTelX);
- FilledFlags = (FilledFlags | 04);
- }
- else if ((FilledFlags&02)==0)
- {
- fscanf (gfpIn, ":%[^\n]s", card.szTelHome);
- FormatNumber (card.szTelHome);
- FilledFlags = (FilledFlags | 02);
- }
- else
- {
- fscanf (gfpIn, ":%[^\n]s", szTemp);
- AppendAsNote (&card, szTemp);
- }
- }
- else
- if( strncmp (szHead, "TEL;HOME", 8) == 0)
- {
- if ((FilledFlags&02) == 0)
- {
- fscanf (gfpIn, ":%[^\n]s", card.szTelHome);
- FormatNumber (card.szTelHome);
- FilledFlags = (FilledFlags | 02);
- }
- else if ((FilledFlags&04)==0)
- {
- fscanf (gfpIn, ":%[^\n]s", card.szTelX);
- FormatNumber (card.szTelX);
- FilledFlags = (FilledFlags | 04);
- }
- else if ((FilledFlags&1)==0)
- {
- fscanf (gfpIn, ":%[^\n]s", card.szTelCell );
- FormatNumber (card.szTelCell);
- FilledFlags = (FilledFlags | 01);
- }
- else
- {
- fscanf (gfpIn, ":%[^\n]s", szTemp);
- AppendAsNote (&card, szTemp);
- }
- }
- else
- if( strncmp (szHead, "TEL", 3) == 0)
- {
- if ((FilledFlags&04)==0)
- {
- fscanf (gfpIn, ":%[^\n]s", card.szTelX);
- FormatNumber (card.szTelX);
- FilledFlags = (FilledFlags | 04);
- }
- else
- if ((FilledFlags&01) == 0) //no overwrite Logic
- {
- fscanf (gfpIn, ":%[^\n]s", card.szTelCell);
- FormatNumber (card.szTelCell);
- FilledFlags = (FilledFlags | 01);
- }
- else
- if ((FilledFlags&02)==0)
- {
- fscanf (gfpIn, ":%[^\n]s", card.szTelHome);
- FormatNumber (card.szTelHome);
- FilledFlags = (FilledFlags | 02);
- }
- else
- {
- fscanf (gfpIn, ":%[^\n]s", szTemp);
- AppendAsNote (&card, szTemp);
- }
- }
- else
- if (strncmp (szHead, "EMAIL;HOME", 10) == 0)
- {
- if ((FilledFlags&8)==0)
- {
- fscanf (gfpIn, ":%[^\n]s", card.szEmailHome);
- FilledFlags = (FilledFlags | 8);
- }
- else
- if((FilledFlags&16)==0)
- {
- fscanf (gfpIn, ":%[^\n]s", card.szEmailX);
- FilledFlags = (FilledFlags | 16);
- }
- else
- {
- fscanf(gfpIn, ":%[^\n]s", szTemp);
- AppendAsNote (&card, szTemp);
- }
- }
- else
- if (strncmp (szHead, "EMAIL", 5) == 0)
- {
- if((FilledFlags & 16) == 0)
- {
- fscanf (gfpIn, ":%[^\n]s", card.szEmailX);
- FilledFlags = (FilledFlags | 16);
- }
- else if ((FilledFlags & 8) == 0)
- {
- fscanf (gfpIn, ":%[^\n]s", card.szEmailHome);
- FilledFlags = (FilledFlags | 8);
- }
- else
- {
- fscanf(gfpIn, ":%[^\n]s", szTemp);
- AppendAsNote (&card, szTemp);
- }
- }
- else
- if (strncmp (szHead, "ORG", 3) == 0)
- {
- fscanf (gfpIn, ":%[^\n]s", card.szOrg );
- }
- else
- if (strncmp (szHead, "TITLE", 3) == 0)
- {
- fscanf (gfpIn, ":%[^\n]s", card.szTitle );
- }
- else
- if ( strncmp (szHead, "END", 3) == 0)
- {
- fscanf (gfpIn, ":%[^\n]s\n", &szTemp);
- break;
- }
- else
- if (( strncmp(szHead, "BEGIN", 5) == 0) || ( strcmp(szHead, "VERSION") == 0))
- {
- //skip line
- fscanf (gfpIn, "%[^\n]s\n", &szTemp);
- }
- else
- if ( strncmp(szHead, "FN", 2) == 0)
- {
- fscanf (gfpIn, "%[^\n]s\n", &szTemp);
- }
- else
- {//append to extra
- fscanf (gfpIn, "%[^\n]s\n", &szTemp);
- if ((FilledFlags & 32) == 0)
- {
- sprintf(card.szExtra, "%s%s", szHead, szTemp);
- FilledFlags = (FilledFlags | 32);
- }
- else
- {
- char szDump[60];
- sprintf (szDump, "%s %s", szHead, szTemp+1);
- AppendAsNote (&card, szDump);
- }
- }
- } //next line/card
- if ((FilledFlags&128) != 128)
- {
- //Write the card to csv.
- fprintf( gfpOut, "%s,%s,%s,%s,%s,", card.szLastName, card.szFirstName, card.szMidName, card.szPreName, card.szSufName);
- fprintf( gfpOut, "%s,", card.szFullName);
- fprintf( gfpOut, "%s,%s,%s,", card.szTelCell, card.szTelHome, card.szTelX);
- fprintf( gfpOut, "%s,%s,%s,%s,%s", card.szEmailHome, card.szEmailX, card.szOrg, card.szTitle, card.szNote);
- fprintf( gfpOut, ",%s\n", card.szExtra);
- printf("\r%4u", (j+1));
- }
- } //while, next card
- printf(" contacts found.");
- return j;
- }
- int
- FindRepeat(
- )
- {
- int i, iMax, j, ch, no, ret;
- char Dummy[50], szFile[50];
- char szContact[2000][20];
- short int szIndex[2000];
- char szNames[2000][60];
- Card card;
- printf("Enter csv filename.");
- scanf("%s", szFile);
- do
- {
- gfpIn = fopen(szFile, "r");
- if (gfpIn == NULL)
- {
- printf("File could not be opened.");
- return -1;
- }
- printf("Processing %s for duplicate contacts.\n", Dummy);
- for (i = iMax = 0; !feof(gfpIn); i++)
- {
- memset(&card, 0, sizeof(card));
- fscanf(gfpIn, "\n%[^,]s", card.szLastName);
- fscanf(gfpIn, ",%[^,]s", card.szFirstName);
- fscanf(gfpIn, ",%[^,]s", card.szMidName);
- fscanf(gfpIn, ",%[^,]s", card.szPreName);
- fscanf(gfpIn, ",%[^,]s", card.szSufName);
- fscanf(gfpIn, ",%[^,]s", card.szFullName); //name
- sprintf(szNames[i], "%s %s %s %s %s",card.szPreName, card.szFirstName, card.szMidName, card.szLastName, card.szSufName);
- //Tel;CELL
- ret = fscanf(gfpIn, ",%[^,]s,", szContact[iMax]);
- if ( ret > 0)
- {
- szIndex[iMax] = i;
- iMax++;
- }
- //TellHome
- ret = fscanf(gfpIn, ",%[^,]s", szContact[iMax]);
- if ( ret > 0)
- {
- szIndex[iMax] = i;
- iMax++;
- }
- ret = fscanf(gfpIn, ",%[^,]s", szContact[iMax]);
- if ( ret > 0)
- {
- szIndex[iMax] = i;
- iMax++;
- }
- fscanf(gfpIn, ",%[^,]s", Dummy);
- fscanf(gfpIn, ",%[^,]s", Dummy);
- fscanf(gfpIn, ",%[^,]s", Dummy);
- fscanf(gfpIn, ",%[^,]s", Dummy);
- fscanf(gfpIn, ",%[^,]s", Dummy);
- fscanf(gfpIn, ",%[^\n]s", Dummy);
- }
- //comparing numbers
- printf("\n card. Number1, Number2 SameCard?");
- for ( i = no = 0; i < iMax; i++)
- {
- for (j = i+1; j < iMax; j++)
- {
- if (CompareNumbers(szContact[i], szContact[j]) == 0)
- {
- printf("\n %3i: %3i %18s %c %s", no+1, szIndex[i]+1, szContact[i], (szIndex[i]==szIndex[j]?'*':' '), szNames[szIndex[i]]);
- printf("\n %3i %18s %s", szIndex[j]+1, szContact[j], szNames[szIndex[j]]);
- no++;
- }
- }
- }
- fclose(gfpIn);
- printf("\n %d repeats found.", no);
- printf("\nDelete the repeating contacts. \nPress 2 to refresh list, Press 1 if done: ");
- scanf("%d", &ch);
- }while (ch==2);
- return 0;
- }
- int
- GetFileNames(
- )
- {
- char szFileIn[100], szFileOut[100];
- printf("\nEnter Input file: ");
- scanf("%s", szFileIn);
- printf("\nEnter Output file: ");
- scanf("%s", szFileOut);
- gfpIn = fopen (szFileIn, "r");
- if (gfpIn == NULL)
- {
- printf("Error opening Infile.");
- return -1;
- }
- gfpOut = fopen (szFileOut, "w");
- if (gfpOut == NULL)
- {
- printf("Error opening Outfile.");
- return -1;
- }
- printf("\n Processing... %s -> %s", szFileIn, szFileOut);
- return 0;
- }
- int
- Menu (
- int *choice
- )
- {
- do
- {
- printf ("\n 1. vcf to csv \n 2. csv to vcf \n 3. Find Repeating numbers \n 4. Exit\n Select: ");
- scanf ("%d", choice);
- }while((*choice > 4) || ( *choice < 1));
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement