Questo sito utilizza cookies solo per scopi di autenticazione sul sito e nient'altro. Nessuna informazione personale viene tracciata. Leggi l'informativa sui cookies.
Username: Password: oppure
C# / VB.NET - Problema lettura stringa json
Forum - C# / VB.NET - Problema lettura stringa json - Pagina 2

Pagine: [ 1 2 3 ] Precedente | Prossimo
Avatar
Carlo (Member)
Guru


Messaggi: 1389
Iscritto: 29/01/2018

Segnala al moderatore
Postato alle 11:11
Sabato, 01/06/2024
Testo quotato

Postato originariamente da Thejuster:

Ora mi tocca solo scrivere un metodo per modificare tutto file.
Nel senso aggiungere i backslash



Se il Json è salvato in un file, non serve modificarlo.
Quando immetti una stringa in una variabile da codice, deve essere delimitata dalle virgolette, se la stringa contiene delle virgolette il compilatore deve essere messo in condizione di distinguere le virgolette che rappresentano testo, dalle virgolette che delimitano la stringa.

Nella memoria i backslash non ci sono.

Se carichi un file Json da file, lo stesso finisce in memoria senza backslash e tutto funziona regolarmente, prova questo codice C che carica il file Thejuster.json allegato:

Codice sorgente - presumibilmente C++

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <stdlib.h>
  4.  
  5. // IndexOf come in C#
  6. int IndexOf(const char *str, const char *subStr, int startPos) {
  7.     int len = strlen(str);
  8.     int subLen = strlen(subStr);
  9.  
  10.     // parametri fuori range
  11.     if (startPos >= len || subLen == 0) return -1;
  12.  
  13.     // ricerca posizione sottostringa
  14.     for (int i = startPos; i <= len - subLen; i++) {
  15.         if (strncmp(&str[i], subStr, subLen) == 0) {
  16.             return i;
  17.         }
  18.     }
  19.     return -1; // non trovato
  20. }
  21.  
  22. // Substring come in C#
  23. char* Substring(const char *str, int startPos, int length) {
  24.     int strLength = strlen(str);
  25.  
  26.     // startPos fuori range
  27.     if (startPos < 0 || startPos >= strLength) {
  28.         return NULL;
  29.     }
  30.  
  31.     // fino alla fine se length è negativo o supera la lunghezza
  32.     if (length < 0 || startPos + length > strLength) {
  33.         length = strLength - startPos;
  34.     }
  35.  
  36.     // memoria per la sottostringa
  37.     char *subStr = (char*)malloc((length + 1) * sizeof(char));
  38.     if (subStr == NULL) return NULL; // memoria non allocata
  39.  
  40.     // Copia il segmento richiesto
  41.     strncpy(subStr, &str[startPos], length);
  42.     subStr[length] = '\0'; // terminatore
  43.  
  44.     return subStr;
  45. }
  46.  
  47. // File_ReadAllLines come in C#
  48. char* File_ReadAllLines(const char *fileName) {
  49.     FILE *file = fopen(fileName, "r");
  50.     if (file == NULL) {
  51.         perror("Failed to open file");
  52.         return NULL;
  53.     }
  54.  
  55.     fseek(file, 0, SEEK_END);
  56.     long length = ftell(file);
  57.     fseek(file, 0, SEEK_SET);
  58.  
  59.     // memoria per il file compreso terminatore
  60.     char *content = (char *)malloc(length + 1);
  61.     if (content == NULL) {
  62.         perror("Failed to allocate memory");
  63.         fclose(file);
  64.         return NULL;
  65.     }
  66.  
  67.     // riempimento buffer
  68.     fread(content, 1, length, file);
  69.     content[length] = '\0';  // terminatore
  70.  
  71.     fclose(file);
  72.     return content;
  73. }
  74.  
  75. int main() {
  76.     // carico il file Json così com'é
  77.     char *jsonString = File_ReadAllLines("Thejuster.json");
  78.     if (jsonString == NULL) return -1;
  79.  
  80.     int id = 0;
  81.     int pos1 = 0;
  82.     int pos2 = 0;
  83.     char searchStr[20]; // Buffer capiente per id fino a 16 cifre
  84.  
  85.     while (pos1 != -1) {
  86.         id++;
  87.         // sottostringa di ricerca
  88.         sprintf(searchStr, "\"id\":%d,", id); // stringa di ricerca = "id:1," quando id = 1
  89.  
  90.         pos1 = IndexOf(jsonString, searchStr, pos1);
  91.         if (pos1 != -1) {
  92.             pos1 = IndexOf(jsonString, "\"name\"", pos1); // stringa di ricerca = "name", il primo dopo id
  93.             if (pos1 != -1) {
  94.                 pos2 = IndexOf(jsonString, ",", pos1); // stringa di ricerca ",", la prima dopo name
  95.                 printf("id:%d %s\n", id, Substring(jsonString, pos1, pos2 - pos1));
  96.             }
  97.         }
  98.     }
  99.     free(jsonString);
  100.     return 0;
  101. }



Carlo ha allegato un file: Thejuster.zip (1547 bytes)
Clicca qui per scaricare il file

Ultima modifica effettuata da Carlo il 01/06/2024 alle 12:46


in programmazione tutto è permesso
PM Quote
Avatar
Carlo (Member)
Guru


Messaggi: 1389
Iscritto: 29/01/2018

Segnala al moderatore
Postato alle 11:28
Sabato, 01/06/2024
Testo quotato

Postato originariamente da Thejuster:

cmq niente non va.
Nel senso se scrivo manualmente la stringa, funziona.
Ma se provo in qualche modo a leggerlo da file mi salta i parametri



Ti ho postato il codice in C che carica il file e fa il parser, alle 11:11


in programmazione tutto è permesso
PM Quote
Avatar
Thejuster (Admin)
Guru^2


Messaggi: 2331
Iscritto: 04/05/2008

Segnala al moderatore
Postato alle 11:54
Sabato, 01/06/2024
no perché e assurda come cosa...

primo punto, aprendo quel file ho

Failed to open file: "Thejuster.json"

in seguito provando a caricare l'altro file quello solo con un id, come detto prima mi salta i parametri restanti.
dandomi come output questo.


id: 1   "\"name\":\"\""
id: 2   "\"name\":\"\""
id: 3   "\"name\":\"\""
id: 4   "\"name\":\"\""

ti allego entrambi i file.



Thejuster ha allegato un file: CommonEvents1.zip (1826 bytes)
Clicca qui per scaricare il file

Ultima modifica effettuata da Thejuster il 01/06/2024 alle 11:56


https://mire.forumfree.it/ - Mire Engine
C# UI Designer
PM Quote
Avatar
Carlo (Member)
Guru


Messaggi: 1389
Iscritto: 29/01/2018

Segnala al moderatore
Postato alle 12:35
Sabato, 01/06/2024
Testo quotato

Postato originariamente da Thejuster:

no perché e assurda come cosa...

primo punto, aprendo quel file ho

Failed to open file: "Thejuster.json"

in seguito provando a caricare l'altro file quello solo con un id, come detto prima mi salta i parametri restanti.
dandomi come output questo.


id: 1   "\"name\":\"\""
id: 2   "\"name\":\"\""
id: 3   "\"name\":\"\""
id: 4   "\"name\":\"\""

ti allego entrambi i file.




Failed to open file: "Thejuster.json" = il file non esiste nel percorso specificato.

I file che hai allegato (CommonEvents1.json e CommonEvents2.json), vengono aperti e correttamente analizzati con il codice che ti ho postato alle 11:11.
CommonEvents1.json da:

Codice sorgente - presumibilmente C# / VB.NET

  1. id:1 "name":"perspective: normal"
  2. id:2 "name":"perspective: 1st person"
  3. id:3 "name":"Texture Personaggi"
  4. id:4 "name":"Perspective Talk"
  5. id:5 "name":"Crea Comandi"
  6. id:6 "name":"Mostra Comandi"
  7. id:7 "name":"Nascondi Comandi"
  8. id:8 "name":"Prospettiva Interni"
  9. id:9 "name":""
  10. id:10 "name":"--battaglia"
  11. id:11 "name":"Eroe Trasparente"
  12. id:12 "name":"Eroe Normale"
  13. id:13 "name":"== Pioggia =="
  14. id:14 "name":"== Nebbia =="
  15. id:15 "name":"= Rimuovi Clima ="
  16. id:16 "name":"= IN MAPPA ="
  17. id:17 "name":"= USCITA MAPPA ="
  18.  
  19. Process returned 0 (0x0)   execution time : 0.045 s
  20. Press any key to continue.



e CommonEvents2.json da:

Codice sorgente - presumibilmente C# / VB.NET

  1. id:1 "name":"CallUI"
  2. id:2 "name":""
  3. id:3 "name":""
  4. id:4 "name":""
  5.  
  6. Process returned 0 (0x0)   execution time : 0.023 s
  7. Press any key to continue.



Il codice che ti ho proposto è in C standard e l'ho scritto e compilato in CODE::BLOCKS.

Questo è strano:

id: 1   "\"name\":\"\""
id: 2   "\"name\":\"\""
id: 3   "\"name\":\"\""
id: 4   "\"name\":\"\""

da dove vengono le backslash??? Il tuo IDE aggiunge i caratteri di escape in automatico??

In allegato l'eseguibile del codice C proposto, compilato con MinGW che carica un file di nome file.json, utile per fare i tuoi test, se tutto funziona vale la pena capire come vengono gestiti i caratteri di escape dal tuo IDE.


Carlo ha allegato un file: Json da file.zip (50961 bytes)
Clicca qui per scaricare il file


in programmazione tutto è permesso
PM Quote
Avatar
Thejuster (Admin)
Guru^2


Messaggi: 2331
Iscritto: 04/05/2008

Segnala al moderatore
Postato alle 16:45
Sabato, 01/06/2024
niente da fare.
Magari sarà il mio codice c++ che non va.
Anche perché il C non lo conosco affatto.

ora come output ho

id:1 "name":""
id:2 "name":""
id:3 "name":""
id:4 "name":""


allego il mio codice

intestazione

Codice sorgente - presumibilmente C++

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <stdlib.h>
  4. #include <iostream>
  5. #include <string>
  6. #include <fstream>
  7. #include <sstream>
  8.  
  9. using namespace std;
  10.  
  11. class JsonReader
  12. {
  13.  
  14. public:
  15.     JsonReader(const string &file);
  16.     int IndexOf(const char *str, const char *subStr, int startPos);
  17.     string Substring(const std::string& str, int startPos, int length);
  18.     string File_ReadAllLines(const string& fileName);
  19.  
  20. };




sorgente
Codice sorgente - presumibilmente C++

  1. #include "jsonreader.h"
  2.  
  3. JsonReader::JsonReader(const string &file)
  4. {
  5.     std::string jsonString = File_ReadAllLines(file);
  6.  
  7.     int id = 0;
  8.     size_t pos1 = 0;
  9.     size_t pos2 = 0;
  10.     std::string searchStr;
  11.  
  12.     while (pos1 != std::string::npos) {
  13.         id++;
  14.         // Sottostringa di ricerca
  15.         searchStr = "\"id\":" + std::to_string(id) + ",";
  16.  
  17.         pos1 = jsonString.find(searchStr, pos1);
  18.         if (pos1 != std::string::npos) {
  19.             pos1 = jsonString.find("\"name\"", pos1);
  20.             if (pos1 != std::string::npos) {
  21.                 pos2 = jsonString.find(",", pos1);
  22.                 if (pos2 != std::string::npos) {
  23.                     std::cout << "id:" << id << " " << jsonString.substr(pos1, pos2 - pos1) << std::endl;
  24.                 } else {
  25.                     std::cout << "id:" << id << " " << jsonString.substr(pos1) << std::endl;
  26.                 }
  27.             }
  28.         }
  29.     }
  30. }
  31.  
  32. int JsonReader::IndexOf(const char *str, const char *subStr, int startPos)
  33. {
  34.     int len = strlen(str);
  35.     int subLen = strlen(subStr);
  36.  
  37.     // parametri fuori range
  38.     if (startPos >= len || subLen == 0) return -1;
  39.  
  40.     // ricerca posizione sottostringa
  41.     for (int i = startPos; i <= len - subLen; i++) {
  42.         if (strncmp(&str[i], subStr, subLen) == 0) {
  43.             return i;
  44.         }
  45.     }
  46.     return -1; // non trovato
  47. }
  48.  
  49. string JsonReader::Substring(const string &str, int startPos, int length)
  50. {
  51.     int strLength = str.length();
  52.  
  53.     // startPos fuori range
  54.     if (startPos < 0 || startPos >= strLength) {
  55.         return "";
  56.     }
  57.  
  58.     // fino alla fine se length è negativo o supera la lunghezza
  59.     if (length < 0 || startPos + length > strLength) {
  60.         length = strLength - startPos;
  61.     }
  62.  
  63.     // Crea e ritorna la sottostringa
  64.     return str.substr(startPos, length);
  65. }
  66.  
  67. string JsonReader::File_ReadAllLines(const string &fileName)
  68. {
  69.     ifstream file(fileName);
  70.     if (!file.is_open()) {
  71.         std::cerr << "Failed to open file" << std::endl;
  72.         return "";
  73.     }
  74.  
  75.     stringstream buffer;
  76.     buffer << file.rdbuf();
  77.  
  78.     return buffer.str();
  79. }



https://mire.forumfree.it/ - Mire Engine
C# UI Designer
PM Quote
Avatar
Carlo (Member)
Guru


Messaggi: 1389
Iscritto: 29/01/2018

Segnala al moderatore
Postato alle 17:45
Sabato, 01/06/2024
Purtroppo non ti so aiutare, con il C mi ci diletto, ma in C++ non ho mai realizzato nulla.

Però so che se copi e incolli il codice C nell'editor C++, deve funzioinare senza modifiche, a conferma ho aperto un progetto nuovo in C++ su CODE::BLOCKS e compilato con GCC in c++17 ISO C++ standard, il codice che ti ho proposto, e tutto ha funzionato senza modifiche.

Anche in C# zero problemi:

Codice sorgente - presumibilmente C#

  1. string jsonString = System.IO.File.ReadAllText("file.json");
  2.  
  3. int pos1 = 0;
  4. int pos2 = 0;
  5. int id = 0;
  6. while (pos1 != -1)
  7. {
  8.     id++;
  9.     pos1 = jsonString.IndexOf("\"id\":" + id.ToString() + ",");
  10.     if (pos1 != -1)
  11.     {
  12.         pos1 = jsonString.IndexOf("\"name\"", pos1);
  13.  
  14.         if (pos1 != -1)
  15.         {
  16.             pos2 = jsonString.IndexOf(",", pos1);
  17.             Console.WriteLine($"id:{id} {jsonString.Substring(pos1, pos2 - pos1)}");
  18.         }
  19.     }
  20. }


Ultima modifica effettuata da Carlo il 01/06/2024 alle 19:58


in programmazione tutto è permesso
PM Quote
Avatar
Carlo (Member)
Guru


Messaggi: 1389
Iscritto: 29/01/2018

Segnala al moderatore
Postato alle 20:06
Sabato, 01/06/2024
Ho fatto convertire il mio codice in C in C++ da ChatGPT, ha funzionato al primo colpo, rispetto al tuo vedo una differenza sul while, per il resto è identico:

Codice sorgente - presumibilmente C++

  1. #include <iostream>
  2. #include <fstream>
  3. #include <sstream>
  4. #include <string>
  5.  
  6. // File_ReadAllText come in C#
  7. std::string File_ReadAllText(const std::string& fileName) {
  8.     std::ifstream file(fileName);
  9.     if (!file) {
  10.         std::cerr << "Failed to open file\n";
  11.         return "";
  12.     }
  13.  
  14.     std::stringstream buffer;
  15.     buffer << file.rdbuf();
  16.     return buffer.str();
  17. }
  18.  
  19. int main() {
  20.     // carico il file Json così com'é
  21.     std::string jsonString = File_ReadAllText("file.json");
  22.     if (jsonString.empty()) return -1;
  23.  
  24.     int id = 0;
  25.     std::size_t pos1 = 0;
  26.     std::size_t pos2 = 0;
  27.     std::string searchStr;
  28.  
  29.     while (true) {
  30.         id++;
  31.         // sottostringa di ricerca
  32.         searchStr = "\"id\":" + std::to_string(id) + ","; // stringa di ricerca = "id:1," quando id = 1
  33.  
  34.         pos1 = jsonString.find(searchStr, pos1);
  35.         if (pos1 == std::string::npos) break;
  36.  
  37.         pos1 = jsonString.find("\"name\"", pos1); // stringa di ricerca = "name", il primo dopo id
  38.         if (pos1 != std::string::npos) {
  39.             pos2 = jsonString.find(",", pos1); // stringa di ricerca ",", la prima dopo name
  40.             std::cout << "id:" << id << " " << jsonString.substr(pos1, pos2 - pos1) << "\n";
  41.         }
  42.     }
  43.     return 0;
  44. }



con le istruzioni native C++ .substr e .find è più veloce, in C sul mio dualcore (duo) impiega 45ms. in C++ 30ms. (il file.json è quello con 17 id)

Ultima modifica effettuata da Carlo il 01/06/2024 alle 20:16


in programmazione tutto è permesso
PM Quote
Avatar
Thejuster (Admin)
Guru^2


Messaggi: 2331
Iscritto: 04/05/2008

Segnala al moderatore
Postato alle 20:07
Sabato, 01/06/2024
ho provato a scaricarlo carlo, ma purtroppo win 11 mi segnala qualsiasi cosa come virus annullando i download :_doubt:

penso mi converrà fare applicazione a parte.
Esempio una su console invisibile recuperandone l'output.
non c'è soluzione.
Anche perché sono sicuro che il codice sia da parte mia, che da parte tua sia corretto.
Quello che non capisco e perché ottengo questo problema.


https://mire.forumfree.it/ - Mire Engine
C# UI Designer
PM Quote
Pagine: [ 1 2 3 ] Precedente | Prossimo